Overview
APE Balance
APE Value
$0.00More Info
Private Name Tags
ContractCreator
Loading...
Loading
Contract Name:
TetherTokenV2
Compiler Version
v0.8.4+commit.c7e474f2
Contract Source Code (Solidity)
/** *Submitted for verification at apescan.io on 2025-02-18 */ // Sources flattened with hardhat v2.22.17 https://hardhat.org // SPDX-License-Identifier: Apache AND MIT // File @openzeppelin/contracts-upgradeable/proxy/utils/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^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 {ERC1967Proxy-constructor}. * * CAUTION: When used with inheritance, manual care must be taken to not invoke a parent initializer twice, or to ensure * that all initializers are idempotent. This is not verified automatically as constructors are by Solidity. */ 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 || !_initialized, "Initializable: contract is already initialized"); bool isTopLevelCall = !_initializing; if (isTopLevelCall) { _initializing = true; _initialized = true; } _; if (isTopLevelCall) { _initializing = false; } } } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /* * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract ContextUpgradeable is Initializable { function __Context_init() internal initializer { __Context_init_unchained(); } function __Context_init_unchained() internal initializer { } function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/access/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^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 { _setOwner(_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 { _setOwner(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"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } uint256[49] private __gap; } // File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^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/token/ERC20/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface for the optional metadata functions from the ERC20 standard. * * _Available since v4.1._ */ interface IERC20MetadataUpgradeable is IERC20Upgradeable { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File @openzeppelin/contracts-upgradeable/token/ERC20/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * For a generic mechanism see {ERC20PresetMinterPauser}. * * TIP: For a detailed writeup see our guide * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * We have followed general OpenZeppelin guidelines: functions revert instead * of returning `false` on failure. This behavior is nonetheless conventional * and does not conflict with the expectations of ERC20 applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. * * Finally, the non-standard {decreaseAllowance} and {increaseAllowance} * functions have been added to mitigate the well-known issues around setting * allowances. See {IERC20-approve}. */ contract ERC20Upgradeable is Initializable, ContextUpgradeable, IERC20Upgradeable, IERC20MetadataUpgradeable { mapping(address => uint256) private _balances; mapping(address => mapping(address => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * The default value of {decimals} is 18. To select a different value for * {decimals} you should overload it. * * All two of these values are immutable: they can only be set once during * construction. */ function __ERC20_init(string memory name_, string memory symbol_) internal initializer { __Context_init_unchained(); __ERC20_init_unchained(name_, symbol_); } function __ERC20_init_unchained(string memory name_, string memory symbol_) internal initializer { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev Returns the number of decimals used to get its user representation. * For example, if `decimals` equals `2`, a balance of `505` tokens should * be displayed to a user as `5,05` (`505 / 10 ** 2`). * * Tokens usually opt for a value of 18, imitating the relationship between * Ether and Wei. This is the value {ERC20} uses, unless this function is * overridden; * * NOTE: This information is only used for _display_ purposes: it in * no way affects any of the arithmetic of the contract, including * {IERC20-balanceOf} and {IERC20-transfer}. */ function decimals() public view virtual override returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual override returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `recipient` cannot be the zero address. * - the caller must have a balance of at least `amount`. */ function transfer(address recipient, uint256 amount) public virtual override returns (bool) { _transfer(_msgSender(), recipient, amount); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual override returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 amount) public virtual override returns (bool) { _approve(_msgSender(), spender, amount); return true; } /** * @dev See {IERC20-transferFrom}. * * Emits an {Approval} event indicating the updated allowance. This is not * required by the EIP. See the note at the beginning of {ERC20}. * * Requirements: * * - `sender` and `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. * - the caller must have allowance for ``sender``'s tokens of at least * `amount`. */ function transferFrom( address sender, address recipient, uint256 amount ) public virtual override returns (bool) { _transfer(sender, recipient, amount); uint256 currentAllowance = _allowances[sender][_msgSender()]; require(currentAllowance >= amount, "ERC20: transfer amount exceeds allowance"); unchecked { _approve(sender, _msgSender(), currentAllowance - amount); } return true; } /** * @dev Atomically increases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. */ function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) { _approve(_msgSender(), spender, _allowances[_msgSender()][spender] + addedValue); return true; } /** * @dev Atomically decreases the allowance granted to `spender` by the caller. * * This is an alternative to {approve} that can be used as a mitigation for * problems described in {IERC20-approve}. * * Emits an {Approval} event indicating the updated allowance. * * Requirements: * * - `spender` cannot be the zero address. * - `spender` must have allowance for the caller of at least * `subtractedValue`. */ function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) { uint256 currentAllowance = _allowances[_msgSender()][spender]; require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero"); unchecked { _approve(_msgSender(), spender, currentAllowance - subtractedValue); } return true; } /** * @dev Moves `amount` of tokens from `sender` to `recipient`. * * This internal function is equivalent to {transfer}, and can be used to * e.g. implement automatic token fees, slashing mechanisms, etc. * * Emits a {Transfer} event. * * Requirements: * * - `sender` cannot be the zero address. * - `recipient` cannot be the zero address. * - `sender` must have a balance of at least `amount`. */ function _transfer( address sender, address recipient, uint256 amount ) internal virtual { require(sender != address(0), "ERC20: transfer from the zero address"); require(recipient != address(0), "ERC20: transfer to the zero address"); _beforeTokenTransfer(sender, recipient, amount); uint256 senderBalance = _balances[sender]; require(senderBalance >= amount, "ERC20: transfer amount exceeds balance"); unchecked { _balances[sender] = senderBalance - amount; } _balances[recipient] += amount; emit Transfer(sender, recipient, amount); _afterTokenTransfer(sender, recipient, amount); } /** @dev Creates `amount` tokens and assigns them to `account`, increasing * the total supply. * * Emits a {Transfer} event with `from` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. */ function _mint(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: mint to the zero address"); _beforeTokenTransfer(address(0), account, amount); _totalSupply += amount; _balances[account] += amount; emit Transfer(address(0), account, amount); _afterTokenTransfer(address(0), account, amount); } /** * @dev Destroys `amount` tokens from `account`, reducing the * total supply. * * Emits a {Transfer} event with `to` set to the zero address. * * Requirements: * * - `account` cannot be the zero address. * - `account` must have at least `amount` tokens. */ function _burn(address account, uint256 amount) internal virtual { require(account != address(0), "ERC20: burn from the zero address"); _beforeTokenTransfer(account, address(0), amount); uint256 accountBalance = _balances[account]; require(accountBalance >= amount, "ERC20: burn amount exceeds balance"); unchecked { _balances[account] = accountBalance - amount; } _totalSupply -= amount; emit Transfer(account, address(0), amount); _afterTokenTransfer(account, address(0), amount); } /** * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens. * * This internal function is equivalent to `approve`, and can be used to * e.g. set automatic allowances for certain subsystems, etc. * * Emits an {Approval} event. * * Requirements: * * - `owner` cannot be the zero address. * - `spender` cannot be the zero address. */ function _approve( address owner, address spender, uint256 amount ) internal virtual { require(owner != address(0), "ERC20: approve from the zero address"); require(spender != address(0), "ERC20: approve to the zero address"); _allowances[owner][spender] = amount; emit Approval(owner, spender, amount); } /** * @dev Hook that is called before any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * will be 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 from, address to, uint256 amount ) internal virtual {} /** * @dev Hook that is called after any transfer of tokens. This includes * minting and burning. * * Calling conditions: * * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens * has been transferred to `to`. * - when `from` is zero, `amount` tokens have been minted for `to`. * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer( address from, address to, uint256 amount ) internal virtual {} uint256[45] private __gap; } // File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. */ interface IERC20PermitUpgradeable { /** * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens, * given ``owner``'s signed approval. * * IMPORTANT: The same issues {IERC20-approve} has related to transaction * ordering also apply here. * * Emits an {Approval} event. * * Requirements: * * - `spender` cannot be the zero address. * - `deadline` must be a timestamp in the future. * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner` * over the EIP712-formatted function arguments. * - the signature must use ``owner``'s current nonce (see {nonces}). * * For more information on the signature format, see the * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP * section]. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File @openzeppelin/contracts-upgradeable/utils/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library CountersUpgradeable { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } } // File @openzeppelin/contracts-upgradeable/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^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. * * Documentation for signature generation: * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js] * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers] */ function recover(bytes32 hash, bytes memory signature) internal pure returns (address) { // Check the signature length // - case 65: r,s,v signature (standard) // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._ if (signature.length == 65) { bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use 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); } else if (signature.length == 64) { bytes32 r; bytes32 vs; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. assembly { r := mload(add(signature, 0x20)) vs := mload(add(signature, 0x40)) } return recover(hash, r, vs); } else { revert("ECDSA: invalid signature length"); } } /** * @dev Overload of {ECDSA-recover} that receives the `r` and `vs` short-signature fields separately. * * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures] * * _Available since v4.2._ */ function recover( bytes32 hash, bytes32 r, bytes32 vs ) internal pure returns (address) { bytes32 s; uint8 v; assembly { s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) v := add(shr(255, vs), 27) } return recover(hash, v, r, s); } /** * @dev Overload of {ECDSA-recover} 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 * produces hash corresponding to the one signed with the * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] * JSON-RPC method as part of EIP-191. * * 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)); } /** * @dev Returns an Ethereum Signed Typed Data, created from a * `domainSeparator` and a `structHash`. This produces hash corresponding * to the one signed with the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] * JSON-RPC method as part of EIP-712. * * See {recover}. */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) { return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash)); } } // File @openzeppelin/contracts-upgradeable/utils/cryptography/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data. * * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible, * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding * they need in their contracts using a combination of `abi.encode` and `keccak256`. * * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA * ({_hashTypedDataV4}). * * The implementation of the domain separator was designed to be as efficient as possible while still properly updating * the chain id to protect against replay attacks on an eventual fork of the chain. * * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask]. * * _Available since v3.4._ */ abstract contract EIP712Upgradeable is Initializable { /* solhint-disable var-name-mixedcase */ bytes32 private _HASHED_NAME; bytes32 private _HASHED_VERSION; bytes32 private constant _TYPE_HASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"); /* solhint-enable var-name-mixedcase */ /** * @dev Initializes the domain separator and parameter caches. * * The meaning of `name` and `version` is specified in * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]: * * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol. * - `version`: the current major version of the signing domain. * * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart * contract upgrade]. */ function __EIP712_init(string memory name, string memory version) internal initializer { __EIP712_init_unchained(name, version); } function __EIP712_init_unchained(string memory name, string memory version) internal initializer { bytes32 hashedName = keccak256(bytes(name)); bytes32 hashedVersion = keccak256(bytes(version)); _HASHED_NAME = hashedName; _HASHED_VERSION = hashedVersion; } /** * @dev Returns the domain separator for the current chain. */ function _domainSeparatorV4() internal view returns (bytes32) { return _buildDomainSeparator(_TYPE_HASH, _EIP712NameHash(), _EIP712VersionHash()); } function _buildDomainSeparator( bytes32 typeHash, bytes32 nameHash, bytes32 versionHash ) private view returns (bytes32) { return keccak256(abi.encode(typeHash, nameHash, versionHash, block.chainid, address(this))); } /** * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this * function returns the hash of the fully encoded EIP712 message for this domain. * * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example: * * ```solidity * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode( * keccak256("Mail(address to,string contents)"), * mailTo, * keccak256(bytes(mailContents)) * ))); * address signer = ECDSA.recover(digest, signature); * ``` */ function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) { return ECDSAUpgradeable.toTypedDataHash(_domainSeparatorV4(), structHash); } /** * @dev The hash of the name parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712NameHash() internal virtual view returns (bytes32) { return _HASHED_NAME; } /** * @dev The hash of the version parameter for the EIP712 domain. * * NOTE: This function reads from storage by default, but can be redefined to return a constant value if gas costs * are a concern. */ function _EIP712VersionHash() internal virtual view returns (bytes32) { return _HASHED_VERSION; } uint256[50] private __gap; } // File @openzeppelin/contracts-upgradeable/token/ERC20/extensions/[email protected] // Original license: SPDX_License_Identifier: MIT pragma solidity ^0.8.0; /** * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * _Available since v3.4._ */ abstract contract ERC20PermitUpgradeable is Initializable, ERC20Upgradeable, IERC20PermitUpgradeable, EIP712Upgradeable { using CountersUpgradeable for CountersUpgradeable.Counter; mapping(address => CountersUpgradeable.Counter) private _nonces; // solhint-disable-next-line var-name-mixedcase bytes32 private _PERMIT_TYPEHASH; /** * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`. * * It's a good idea to use the same `name` that is defined as the ERC20 token name. */ function __ERC20Permit_init(string memory name) internal initializer { __Context_init_unchained(); __EIP712_init_unchained(name, "1"); __ERC20Permit_init_unchained(name); } function __ERC20Permit_init_unchained(string memory name) internal initializer { _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");} /** * @dev See {IERC20Permit-permit}. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256(abi.encode(_PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline)); bytes32 hash = _hashTypedDataV4(structHash); address signer = ECDSAUpgradeable.recover(hash, v, r, s); require(signer == owner, "ERC20Permit: invalid signature"); _approve(owner, spender, value); } /** * @dev See {IERC20Permit-nonces}. */ function nonces(address owner) public view virtual override returns (uint256) { return _nonces[owner].current(); } /** * @dev See {IERC20Permit-DOMAIN_SEPARATOR}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view override returns (bytes32) { return _domainSeparatorV4(); } /** * @dev "Consume a nonce": return the current value and increment. * * _Available since v4.1._ */ function _useNonce(address owner) internal virtual returns (uint256 current) { CountersUpgradeable.Counter storage nonce = _nonces[owner]; current = nonce.current(); nonce.increment(); } uint256[49] private __gap; } // File contracts/Tether/util/MessageHashUtils.sol /** * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ pragma solidity >=0.6.12 <0.9.0; /** * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing. * * The library provides methods for generating a hash of a message that conforms to the * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712] * specifications. */ library MessageHashUtils { /** * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`). * Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/21bb89ef5bfc789b9333eb05e3ba2b7b284ac77c/contracts/utils/cryptography/MessageHashUtils.sol * * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with * `\x19\x01` and hashing the result. It corresponds to the hash signed by the * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712. * * @param domainSeparator Domain separator * @param structHash Hashed EIP-712 data struct * @return digest The keccak256 digest of an EIP-712 typed data */ function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) { /// @solidity memory-safe-assembly assembly { let ptr := mload(0x40) mstore(ptr, "\x19\x01") mstore(add(ptr, 0x02), domainSeparator) mstore(add(ptr, 0x22), structHash) digest := keccak256(ptr, 0x42) } } } // File contracts/Tether/interfaces/IERC1271.sol /** * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ pragma solidity >=0.6.12 <0.9.0; /** * @dev Interface of the ERC1271 standard signature validation method for * contracts as defined in https://eips.ethereum.org/EIPS/eip-1271[ERC-1271]. */ interface IERC1271 { /** * @dev Should return whether the signature provided is valid for the provided data * @param hash Hash of the data to be signed * @param signature Signature byte array associated with the provided data hash * @return magicValue bytes4 magic value 0x1626ba7e when function passes */ function isValidSignature(bytes32 hash, bytes memory signature) external view returns (bytes4 magicValue); } // File contracts/Tether/util/ECRecover.sol /** * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ pragma solidity >=0.6.12 <0.9.0; /** * @title ECRecover * @notice A library that provides a safe ECDSA recovery function */ library ECRecover { /** * @notice Recover signer's address from a signed message * @dev Adapted from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/65e4ffde586ec89af3b7e9140bdc9235d1254853/contracts/cryptography/ECDSA.sol * Modifications: Accept v, r, and s as separate arguments * @param digest Keccak-256 hash digest of the signed message * @param v v of the signature * @param r r of the signature * @param s s of the signature * @return Signer address */ function recover( bytes32 digest, 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. if ( uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0 ) { revert("ECRecover: invalid signature 's' value"); } if (v != 27 && v != 28) { revert("ECRecover: invalid signature 'v' value"); } // If the signature is valid (and not malleable), return the signer address address signer = ecrecover(digest, v, r, s); require(signer != address(0), "ECRecover: invalid signature"); return signer; } /** * @notice Recover signer's address from a signed message * @dev Adapted from: https://github.com/OpenZeppelin/openzeppelin-contracts/blob/0053ee040a7ff1dbc39691c9e67a69f564930a88/contracts/utils/cryptography/ECDSA.sol * @param digest Keccak-256 hash digest of the signed message * @param signature Signature byte array associated with hash * @return Signer address */ function recover(bytes32 digest, bytes memory signature) internal pure returns (address) { require(signature.length == 65, "ECRecover: invalid signature length"); bytes32 r; bytes32 s; uint8 v; // ecrecover takes the signature parameters, and the only way to get them // currently is to use assembly. /// @solidity memory-safe-assembly assembly { r := mload(add(signature, 0x20)) s := mload(add(signature, 0x40)) v := byte(0, mload(add(signature, 0x60))) } return recover(digest, v, r, s); } } // File contracts/Tether/util/SignatureChecker.sol /** * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ pragma solidity >=0.6.12 <0.9.0; /** * @dev Signature verification helper that can be used instead of `ECRecover.recover` to seamlessly support both ECDSA * signatures from externally owned accounts (EOAs) as well as ERC1271 signatures from smart contract wallets. * * Adapted from https://github.com/OpenZeppelin/openzeppelin-contracts/blob/21bb89ef5bfc789b9333eb05e3ba2b7b284ac77c/contracts/utils/cryptography/SignatureChecker.sol */ library SignatureChecker { /** * @dev Checks if a signature is valid for a given signer and data hash. If the signer is a smart contract, the * signature is validated against that smart contract using ERC1271, otherwise it's validated using `ECRecover.recover`. * @param signer Address of the claimed signer * @param digest Keccak-256 hash digest of the signed message * @param signature signature byte array associated with hash */ function isValidSignatureNow( address signer, bytes32 digest, bytes memory signature ) internal view returns (bool) { if (!isContract(signer)) { return ECRecover.recover(digest, signature) == signer; } return isValidERC1271SignatureNow(signer, digest, signature); } /** * @dev Checks if a signature is valid for a given signer and data hash. The signature is validated * against the signer smart contract using ERC1271. * @param signer Address of the claimed signer * @param digest Keccak-256 hash digest of the signed message * @param signature Signature byte array associated with hash * * NOTE: Unlike ECDSA signatures, contract signatures are revocable, and the outcome of this function can thus * change through time. It could return true at block N and false at block N+1 (or the opposite). */ function isValidERC1271SignatureNow( address signer, bytes32 digest, bytes memory signature ) internal view returns (bool) { (bool success, bytes memory result) = signer.staticcall( abi.encodeWithSelector( IERC1271.isValidSignature.selector, digest, signature ) ); return (success && result.length >= 32 && abi.decode(result, (bytes32)) == bytes32(IERC1271.isValidSignature.selector)); } /** * @dev Checks if the input address is a smart contract. */ function isContract(address addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(addr) } return size > 0; } } // File contracts/Tether/EIP3009.sol /** * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ pragma solidity >=0.6.12 <0.9.0; /** * @title EIP-3009 * @notice Provide internal implementation for gas-abstracted transfers * @dev Contracts that inherit from this must wrap these with publicly * accessible functions, optionally adding modifiers where necessary */ abstract contract EIP3009 { bytes32 public constant TRANSFER_WITH_AUTHORIZATION_TYPEHASH = keccak256("TransferWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)"); bytes32 public constant RECEIVE_WITH_AUTHORIZATION_TYPEHASH = keccak256("ReceiveWithAuthorization(address from,address to,uint256 value,uint256 validAfter,uint256 validBefore,bytes32 nonce)"); bytes32 public constant CANCEL_AUTHORIZATION_TYPEHASH = keccak256("CancelAuthorization(address authorizer,bytes32 nonce)"); /** * @dev authorizer address => nonce => bool (true if nonce is used) */ mapping(address => mapping(bytes32 => bool)) private _authorizationStates; event AuthorizationUsed(address indexed authorizer, bytes32 indexed nonce); event AuthorizationCanceled( address indexed authorizer, bytes32 indexed nonce ); function domainSeparator() internal virtual view returns (bytes32); /** * @notice Returns the state of an authorization * @dev Nonces are randomly generated 32-byte data unique to the * authorizer's address * @param authorizer Authorizer's address * @param nonce Nonce of the authorization * @return True if the nonce is used */ function authorizationState(address authorizer, bytes32 nonce) external view returns (bool) { return _authorizationStates[authorizer][nonce]; } /** * @notice Execute a transfer with a signed authorization * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param signature signature in bytes */ function _transferWithAuthorizationValidityCheck( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes memory signature ) internal { _requireValidAuthorization(from, nonce, validAfter, validBefore); _requireValidSignature( from, keccak256( abi.encode( TRANSFER_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce ) ), signature ); _markAuthorizationAsUsed(from, nonce); } /** * @notice Receive a transfer with a signed authorization from the payer * @dev This has an additional check to ensure that the payee's address * matches the caller of this function to prevent front-running attacks. * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param signature signature in bytes */ function _receiveWithAuthorizationValidityCheck( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes memory signature ) internal { require(to == msg.sender, "TetherToken: to != msg.sender"); _requireValidAuthorization(from, nonce, validAfter, validBefore); _requireValidSignature( from, keccak256( abi.encode( RECEIVE_WITH_AUTHORIZATION_TYPEHASH, from, to, value, validAfter, validBefore, nonce ) ), signature ); _markAuthorizationAsUsed(from, nonce); } function _cancelAuthorization( address authorizer, bytes32 nonce, bytes memory signature ) internal { _requireUnusedAuthorization(authorizer, nonce); _requireValidSignature( authorizer, keccak256( abi.encode(CANCEL_AUTHORIZATION_TYPEHASH, authorizer, nonce) ), signature ); _authorizationStates[authorizer][nonce] = true; emit AuthorizationCanceled(authorizer, nonce); } /** * @notice Attempt to cancel an authorization * @param authorizer Authorizer's address * @param nonce Nonce of the authorization * @param v v of the signature * @param r r of the signature * @param s s of the signature */ function cancelAuthorization( address authorizer, bytes32 nonce, uint8 v, bytes32 r, bytes32 s ) public { _cancelAuthorization(authorizer, nonce, abi.encodePacked(r,s,v)); } /** * @notice Attempt to cancel an authorization * @dev Works only if the authorization is not yet used. * EOA wallet signatures should be packed in the order of r, s, v. * @param authorizer Authorizer's address * @param nonce Nonce of the authorization * @param signature Signature bytes signed by an EOA wallet or a contract wallet */ function cancelAuthorization( address authorizer, bytes32 nonce, bytes memory signature ) external { _cancelAuthorization(authorizer, nonce, signature); } /** * @notice Validates that signature against input data struct * @param signer Signer's address * @param dataHash Hash of encoded data struct * @param signature signature in bytes */ function _requireValidSignature( address signer, bytes32 dataHash, bytes memory signature ) private view { require( SignatureChecker.isValidSignatureNow( signer, MessageHashUtils.toTypedDataHash(domainSeparator(), dataHash), signature ), "TetherToken: invalid signature" ); } /** * @notice Check that an authorization is unused * @param authorizer Authorizer's address * @param nonce Nonce of the authorization */ function _requireUnusedAuthorization(address authorizer, bytes32 nonce) private view { require( !_authorizationStates[authorizer][nonce], "TetherToken: auth invalid" ); } /** * @notice Check that authorization is valid * @param authorizer Authorizer's address * @param nonce Nonce of the authorization * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) */ function _requireValidAuthorization( address authorizer, bytes32 nonce, uint256 validAfter, uint256 validBefore ) private view { require( block.timestamp > validAfter, "TetherToken: auth early" ); require(block.timestamp < validBefore, "TetherToken: auth expired"); _requireUnusedAuthorization(authorizer, nonce); } /** * @notice Mark an authorization as used * @param authorizer Authorizer's address * @param nonce Nonce of the authorization */ function _markAuthorizationAsUsed(address authorizer, bytes32 nonce) private { _authorizationStates[authorizer][nonce] = true; emit AuthorizationUsed(authorizer, nonce); } uint256[49] private __gap; } // File contracts/Tether/WithBlockedList.sol // Original license: SPDX_License_Identifier: Apache pragma solidity 0.8.4; /* Copyright Tether.to 2020 Author Will Harborne Licensed under the Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0 */ contract WithBlockedList is OwnableUpgradeable { /** * @dev Reverts if called by a blocked account */ modifier onlyNotBlocked() { require(!isBlocked[_msgSender()], "Blocked: msg.sender is blocked"); _; } mapping (address => bool) public isBlocked; function addToBlockedList (address _user) public onlyOwner { isBlocked[_user] = true; emit BlockPlaced(_user); } function removeFromBlockedList (address _user) public onlyOwner { isBlocked[_user] = false; emit BlockReleased(_user); } event BlockPlaced(address indexed _user); event BlockReleased(address indexed _user); } // File contracts/Tether/TetherToken.sol // Original license: SPDX_License_Identifier: Apache pragma solidity 0.8.4; /* Copyright Tether.to 2024 Version 2.0(a) Licensed under the Apache License, Version 2.0 http://www.apache.org/licenses/LICENSE-2.0 */ contract TetherToken is Initializable, ERC20PermitUpgradeable, OwnableUpgradeable, WithBlockedList { // Unused variable retained to preserve storage slots across upgrades mapping(address => bool) public isTrusted; uint8 private tetherDecimals; function initialize( string memory _name, string memory _symbol, uint8 _decimals ) public initializer { tetherDecimals = _decimals; __Ownable_init(); __ERC20_init(_name, _symbol); __ERC20Permit_init(_name); } function decimals() public view virtual override returns (uint8) { return tetherDecimals; } function _beforeTokenTransfer( address from, address to, uint256 ) internal virtual override { require(!isBlocked[from] || msg.sender == owner(), "TetherToken: from is blocked"); require( to != address(this), "TetherToken: transfer to the contract address" ); } function transferFrom( address _sender, address _recipient, uint256 _amount ) public virtual override onlyNotBlocked returns (bool) { return super.transferFrom(_sender, _recipient, _amount); } function multiTransfer ( address[] calldata _recipients, uint256[] calldata _values ) external { require( _recipients.length == _values.length, "TetherToken: multiTransfer mismatch" ); for (uint256 i = 0; i < _recipients.length; i++) { transfer(_recipients[i], _values[i]); } } function mint(address _destination, uint256 _amount) public onlyOwner { _mint(_destination, _amount); emit Mint(_destination, _amount); } function burnFrom(address _from, uint256 _amount) public onlyOwner { _burn(_from, _amount); emit Burn(_from, _amount); } function redeem(uint256 _amount) public onlyOwner { _burn(owner(), _amount); emit Redeem(_amount); } function destroyBlockedFunds(address _blockedUser) public onlyOwner { require(isBlocked[_blockedUser], "TetherToken: user is not blocked"); uint256 blockedFunds = balanceOf(_blockedUser); _burn(_blockedUser, blockedFunds); emit DestroyedBlockedFunds(_blockedUser, blockedFunds); } event Mint(address indexed _destination, uint256 _amount); event Burn(address indexed _from, uint256 _amount); event Redeem(uint256 _amount); event DestroyedBlockedFunds(address indexed _blockedUser, uint256 _balance); } // File contracts/Tether/TetherTokenV2.sol // Original license: SPDX_License_Identifier: Apache pragma solidity 0.8.4; contract TetherTokenV2 is TetherToken, EIP3009 { bytes32 internal constant _PERMIT_TYPEHASH = keccak256( "Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)" ); constructor () initializer {} function domainSeparator() internal view virtual override returns (bytes32) { return _domainSeparatorV4(); } /** * The following applies to the following function and comments to that function: * * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ function _permit( address owner_, address spender, uint256 value, uint256 deadline, bytes memory signature ) internal { require(block.timestamp <= deadline, "ERC20Permit: expired deadline"); bytes32 structHash = keccak256( abi.encode( _PERMIT_TYPEHASH, owner_, spender, value, _useNonce(owner_), deadline ) ); bytes32 hash = _hashTypedDataV4(structHash); require( SignatureChecker.isValidSignatureNow(owner_, hash, signature), "EIP2612: invalid signature" ); _approve(owner_, spender, value); } /** * @notice Update allowance with a signed permit * @param owner_ Token owner's address * @param spender Spender's address * @param value Amount of allowance * @param deadline The time at which the signature expires (unix time) * @param v signature component v * @param r signature component r * @param s signature component s */ function permit( address owner_, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) public virtual override { _permit(owner_, spender, value, deadline, abi.encodePacked(r, s, v)); } /** * The following applies to the following function and comments to that function: * * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ /** * @notice Update allowance with a signed permit * @dev EOA wallet signatures should be packed in the order of r, s, v. * @param owner_ Token owner's address (Authorizer) * @param spender Spender's address * @param value Amount of allowance * @param deadline The time at which the signature expires (unix time), or max uint256 value to signal no expiration * @param signature Signature bytes signed by an EOA wallet or a contract wallet */ function permit( address owner_, address spender, uint256 value, uint256 deadline, bytes memory signature ) external { _permit(owner_, spender, value, deadline, signature); } /** * The following applies to the following function and comments to that function: * * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ /** * @notice Execute a transfer with a signed authorization * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param v v of the signature * @param r r of the signature * @param s s of the signature */ function transferWithAuthorization( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s ) public onlyNotBlocked { _transferWithAuthorizationValidityCheck( from, to, value, validAfter, validBefore, nonce, abi.encodePacked(r, s, v) ); _transfer(from, to, value); } /** * The following applies to the following function and comments to that function: * * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ /** * @notice Execute a transfer with a signed authorization * @dev EOA wallet signatures should be packed in the order of r, s, v. * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param signature Signature bytes signed by an EOA wallet or a contract wallet */ function transferWithAuthorization( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes memory signature ) external onlyNotBlocked { _transferWithAuthorizationValidityCheck( from, to, value, validAfter, validBefore, nonce, signature ); _transfer(from, to, value); } /** * The following applies to the following function and comments to that function: * * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ /** * @notice Receive a transfer with a signed authorization from the payer * @dev This has an additional check to ensure that the payee's address * matches the caller of this function to prevent front-running attacks. * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param v v of the signature * @param r r of the signature * @param s s of the signature */ function receiveWithAuthorization( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, uint8 v, bytes32 r, bytes32 s ) public onlyNotBlocked { _receiveWithAuthorizationValidityCheck( from, to, value, validAfter, validBefore, nonce, abi.encodePacked(r, s, v) ); _transfer(from, to, value); } /** * The following applies to the following function and comments to that function: * * * Copyright (c) 2023, Circle Internet Financial, LLC. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * --------------------------------------------------------------------- * * Adapted by Tether.to 2024 for greater flexibility and reusability */ /** * @notice Receive a transfer with a signed authorization from the payer * @dev This has an additional check to ensure that the payee's address * matches the caller of this function to prevent front-running attacks. * EOA wallet signatures should be packed in the order of r, s, v. * @param from Payer's address (Authorizer) * @param to Payee's address * @param value Amount to be transferred * @param validAfter The time after which this is valid (unix time) * @param validBefore The time before which this is valid (unix time) * @param nonce Unique nonce * @param signature Signature bytes signed by an EOA wallet or a contract wallet */ function receiveWithAuthorization( address from, address to, uint256 value, uint256 validAfter, uint256 validBefore, bytes32 nonce, bytes memory signature ) external onlyNotBlocked { _receiveWithAuthorizationValidityCheck( from, to, value, validAfter, validBefore, nonce, signature ); _transfer(from, to, value); } uint256[48] private __gap; }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationCanceled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"authorizer","type":"address"},{"indexed":true,"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"AuthorizationUsed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"}],"name":"BlockPlaced","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_user","type":"address"}],"name":"BlockReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Burn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_blockedUser","type":"address"},{"indexed":false,"internalType":"uint256","name":"_balance","type":"uint256"}],"name":"DestroyedBlockedFunds","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"_destination","type":"address"},{"indexed":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Mint","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":false,"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"Redeem","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":"CANCEL_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"RECEIVE_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRANSFER_WITH_AUTHORIZATION_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"addToBlockedList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","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":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"}],"name":"authorizationState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"authorizer","type":"address"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"cancelAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_blockedUser","type":"address"}],"name":"destroyBlockedFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"},{"internalType":"uint8","name":"_decimals","type":"uint8"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isBlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isTrusted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_destination","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_recipients","type":"address[]"},{"internalType":"uint256[]","name":"_values","type":"uint256[]"}],"name":"multiTransfer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"receiveWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"redeem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"}],"name":"removeFromBlockedList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"_sender","type":"address"},{"internalType":"address","name":"_recipient","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"validAfter","type":"uint256"},{"internalType":"uint256","name":"validBefore","type":"uint256"},{"internalType":"bytes32","name":"nonce","type":"bytes32"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"transferWithAuthorization","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50600054610100900460ff16806200002c575060005460ff16155b620000945760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000b7576000805461ffff19166101011790555b8015620000ca576000805461ff00191690555b50613fc480620000db6000396000f3fe608060405234801561001057600080fd5b50600436106102925760003560e01c806388b7ab6311610160578063cf092995116100d8578063e3ee160e1161008c578063ef55bec611610071578063ef55bec61461061a578063f2fde38b1461062d578063fbac39511461064057600080fd5b8063e3ee160e146105c0578063e94a0102146105d357600080fd5b8063d9169487116100bd578063d916948714610540578063db006a7514610567578063dd62ed3e1461057a57600080fd5b8063cf0929951461051a578063d505accf1461052d57600080fd5b80639fd5a6cf1161012f578063a457c2d711610114578063a457c2d7146104e1578063a9059cbb146104f4578063b7b728991461050757600080fd5b80639fd5a6cf146104a7578063a0cc6a68146104ba57600080fd5b806388b7ab63146104405780638da5cb5b1461045357806395d89b411461047b57806396d648791461048357600080fd5b80633644e5151161020e57806370a08231116101c257806379cc6790116101a757806379cc6790146103f35780637ecebe00146104065780637f2eecc31461041957600080fd5b806370a08231146103b5578063715018a6146103eb57600080fd5b80633c7c9b90116101f35780633c7c9b901461037c57806340c10f191461038f5780635a049a70146103a257600080fd5b80633644e51514610361578063395093511461036957600080fd5b806318160ddd116102655780631e89d5451161024a5780631e89d5451461032557806323b872dd14610338578063313ce5671461034b57600080fd5b806318160ddd146103005780631a14f4491461031257600080fd5b806306fdde0314610297578063095ea7b3146102b55780630e27a385146102d85780631624f6c6146102ed575b600080fd5b61029f610663565b6040516102ac9190613e3b565b60405180910390f35b6102c86102c3366004613be7565b6106f5565b60405190151581526020016102ac565b6102eb6102e6366004613987565b61070b565b005b6102eb6102fb366004613d33565b6108a4565b6035545b6040519081526020016102ac565b6102eb610320366004613987565b610a06565b6102eb610333366004613cb2565b610afb565b6102c86103463660046139d3565b610c45565b6101005460405160ff90911681526020016102ac565b610304610cd4565b6102c8610377366004613be7565b610ce3565b6102eb61038a366004613987565b610d2c565b6102eb61039d366004613be7565b610e24565b6102eb6103b0366004613c65565b610ef7565b6103046103c3366004613987565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b6102eb610f53565b6102eb610401366004613be7565b610fe0565b610304610414366004613987565b6110b3565b6103047fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b6102eb61044e366004613a7e565b6110e0565b60cc5460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102ac565b61029f61117d565b6102c8610491366004613987565b60ff602081905260009182526040909120541681565b6102eb6104b5366004613a0e565b61118c565b6103047f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6102c86104ef366004613be7565b611199565b6102c8610502366004613be7565b611271565b6102eb610515366004613c10565b61127e565b6102eb610528366004613a7e565b61128e565b6102eb61053b366004613b7e565b611317565b6103047f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b6102eb610575366004613da4565b61137d565b6103046105883660046139a1565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b6102eb6105ce366004613b01565b61145c565b6102c86105e1366004613be7565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815261010160209081526040808320938352929052205460ff1690565b6102eb610628366004613b01565b611554565b6102eb61063b366004613987565b611636565b6102c861064e366004613987565b60fe6020526000908152604090205460ff1681565b60606036805461067290613ea9565b80601f016020809104026020016040519081016040528092919081815260200182805461069e90613ea9565b80156106eb5780601f106106c0576101008083540402835291602001916106eb565b820191906000526020600020905b8154815290600101906020018083116106ce57829003601f168201915b5050505050905090565b6000610702338484611766565b50600192915050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260fe602052604090205460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546574686572546f6b656e3a2075736572206973206e6f7420626c6f636b65646044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603360205260409020546108508282611919565b8173ffffffffffffffffffffffffffffffffffffffff167f6a2859ae7902313752498feb80a014e6e7275fe964c79aa965db815db1c7f1e98260405161089891815260200190565b60405180910390a25050565b600054610100900460ff16806108bd575060005460ff16155b610949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff1615801561098857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61010080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff84161790556109be611b12565b6109c88484611c37565b6109d184611d60565b8015610a0057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610a87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f665918c9e02eb2fd85acca3969cb054fc84c138e60ec4af22ab6ef2fd4c93c279190a250565b828114610b8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f546574686572546f6b656e3a206d756c74695472616e73666572206d69736d6160448201527f74636800000000000000000000000000000000000000000000000000000000006064820152608401610788565b60005b83811015610c3e57610c2b858583818110610bd1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610be69190613987565b848484818110610c1f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135611271565b5080610c3681613ef7565b915050610b8d565b5050505050565b33600090815260fe602052604081205460ff1615610cbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b610cca848484611ec7565b90505b9392505050565b6000610cde611fad565b905090565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091610702918590610d27908690613e4e565b611766565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f406bbf2d8d145125adf1198d2cf8a67c66cc4bb0ab01c37dccd4f7c0aae1e7c79190a250565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610ea5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b610eaf8282612028565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161089891815260200190565b60408051602081018490529081018290527fff0000000000000000000000000000000000000000000000000000000000000060f885901b166060820152610c3e9086908690606101604051602081830303815290604052612154565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610fd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b610fde600061225a565b565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b61106b8282611919565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161089891815260200190565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b33600090815260fe602052604090205460ff161561115a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b611169878787878787876122d1565b6111748787876123e2565b50505050505050565b60606037805461067290613ea9565b610c3e85858585856126a0565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120548281101561125a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610788565b6112673385858403611766565b5060019392505050565b60006107023384846123e2565b611289838383612154565b505050565b33600090815260fe602052604090205460ff1615611308576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b6111698787878787878761281f565b6111748787878786868960405160200161136993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b6040516020818303038152906040526126a0565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146113fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b61142661142060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b82611919565b6040518181527f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a449060200160405180910390a150565b33600090815260fe602052604090205460ff16156114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b61153e89898989898988888b60405160200161152a93929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b60405160208183030381529060405261281f565b6115498989896123e2565b505050505050505050565b33600090815260fe602052604090205460ff16156115ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b61153e89898989898988888b60405160200161162293929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b6040516020818303038152906040526122d1565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146116b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff811661175a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610788565b6117638161225a565b50565b73ffffffffffffffffffffffffffffffffffffffff8316611808576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff82166118ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166119bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610788565b6119c8826000836128a7565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015611a7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603360205260408120838303905560358054849290611aba908490613e66565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600054610100900460ff1680611b2b575060005460ff16155b611bb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611bf657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611bfe6129ff565b611c06612b13565b801561176357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680611c50575060005460ff16155b611cdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611d1b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611d236129ff565b611d2d8383612c00565b801561128957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680611d79575060005460ff16155b611e05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611e4457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611e4c6129ff565b611e8b826040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250612d3f565b611e9482612e73565b8015611ec357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b6000611ed48484846123e2565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015611f95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610788565b611fa28533858403611766565b506001949350505050565b6000610cde7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611fdc60655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff82166120a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610788565b6120b1600083836128a7565b80603560008282546120c39190613e4e565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040812080548392906120fd908490613e4e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b61215e8383612fad565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429602082015273ffffffffffffffffffffffffffffffffffffffff851691810191909152606081018390526121d39084906080015b6040516020818303038152906040528051906020012083613049565b73ffffffffffffffffffffffffffffffffffffffff831660008181526101016020908152604080832086845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b60cc805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b73ffffffffffffffffffffffffffffffffffffffff86163314612350576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546574686572546f6b656e3a20746f20213d206d73672e73656e6465720000006044820152606401610788565b61235c878386866130ff565b604080517fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526123d8908890610100016121b7565b61117487836131db565b73ffffffffffffffffffffffffffffffffffffffff8316612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff8216612528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610788565b6125338383836128a7565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156125e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061262d908490613e4e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161269391815260200190565b60405180910390a3610a00565b8142111561270a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610788565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98686866127398a613261565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810184905260e00160405160208183030381529060405280519060200120905060006127a182613296565b90506127ae8782856132ff565b612814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f454950323631323a20696e76616c6964207369676e61747572650000000000006044820152606401610788565b611174878787611766565b61282b878386866130ff565b604080517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526123d8908890610100016121b7565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260fe602052604090205460ff1615806128f3575060cc5473ffffffffffffffffffffffffffffffffffffffff1633145b612959576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546574686572546f6b656e3a2066726f6d20697320626c6f636b6564000000006044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff8216301415611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f546574686572546f6b656e3a207472616e7366657220746f2074686520636f6e60448201527f74726163742061646472657373000000000000000000000000000000000000006064820152608401610788565b600054610100900460ff1680612a18575060005460ff16155b612aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611c0657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016610101179055801561176357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680612b2c575060005460ff16155b612bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612bf757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611c063361225a565b600054610100900460ff1680612c19575060005460ff16155b612ca5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612ce457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8251612cf79060369060208601906137c5565b508151612d0b9060379060208501906137c5565b50801561128957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680612d58575060005460ff16155b612de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612e2357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8251602080850191909120835191840191909120606591909155606655801561128957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680612e8c575060005460ff16155b612f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612f5757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a558015611ec357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526101016020908152604080832084845290915290205460ff1615611ec3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a206175746820696e76616c6964000000000000006044820152606401610788565b61309983613093613058610cd4565b856040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b836132ff565b611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546574686572546f6b656e3a20696e76616c6964207369676e617475726500006044820152606401610788565b814211613168576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546574686572546f6b656e3a2061757468206561726c790000000000000000006044820152606401610788565b8042106131d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a20617574682065787069726564000000000000006044820152606401610788565b610a008484612fad565b73ffffffffffffffffffffffffffffffffffffffff821660008181526101016020908152604080832085845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006110da6132a3611fad565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000833b613346578373ffffffffffffffffffffffffffffffffffffffff166133288484613351565b73ffffffffffffffffffffffffffffffffffffffff16149050610ccd565b610cca84848461340c565b600081516041146133e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45435265636f7665723a20696e76616c6964207369676e6174757265206c656e60448201527f67746800000000000000000000000000000000000000000000000000000000006064820152608401610788565b60208201516040830151606084015160001a61340286828585613569565b9695505050505050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401613443929190613e22565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516134cc9190613e06565b600060405180830381855afa9150503d8060008114613507576040519150601f19603f3d011682016040523d82523d6000602084013e61350c565b606091505b509150915081801561352057506020815110155b8015613402575080517f1626ba7e000000000000000000000000000000000000000000000000000000009061355e9083016020908101908401613d1b565b149695505050505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561361b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027732760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610788565b8360ff16601b1415801561363357508360ff16601c14155b156136c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027762760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610788565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613714573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45435265636f7665723a20696e76616c6964207369676e6174757265000000006044820152606401610788565b95945050505050565b8280546137d190613ea9565b90600052602060002090601f0160209004810192826137f35760008555613839565b82601f1061380c57805160ff1916838001178555613839565b82800160010185558215613839579182015b8281111561383957825182559160200191906001019061381e565b50613845929150613849565b5090565b5b80821115613845576000815560010161384a565b803573ffffffffffffffffffffffffffffffffffffffff8116811461388257600080fd5b919050565b60008083601f840112613898578081fd5b50813567ffffffffffffffff8111156138af578182fd5b6020830191508360208260051b85010111156138ca57600080fd5b9250929050565b600082601f8301126138e1578081fd5b813567ffffffffffffffff808211156138fc576138fc613f5f565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561394257613942613f5f565b8160405283815286602085880101111561395a578485fd5b8360208701602083013792830160200193909352509392505050565b803560ff8116811461388257600080fd5b600060208284031215613998578081fd5b610ccd8261385e565b600080604083850312156139b3578081fd5b6139bc8361385e565b91506139ca6020840161385e565b90509250929050565b6000806000606084860312156139e7578081fd5b6139f08461385e565b92506139fe6020850161385e565b9150604084013590509250925092565b600080600080600060a08688031215613a25578081fd5b613a2e8661385e565b9450613a3c6020870161385e565b93506040860135925060608601359150608086013567ffffffffffffffff811115613a65578182fd5b613a71888289016138d1565b9150509295509295909350565b600080600080600080600060e0888a031215613a98578182fd5b613aa18861385e565b9650613aaf6020890161385e565b955060408801359450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff811115613ae6578182fd5b613af28a828b016138d1565b91505092959891949750929550565b60008060008060008060008060006101208a8c031215613b1f578182fd5b613b288a61385e565b9850613b3660208b0161385e565b975060408a0135965060608a0135955060808a0135945060a08a01359350613b6060c08b01613976565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a031215613b98578283fd5b613ba18861385e565b9650613baf6020890161385e565b95506040880135945060608801359350613bcb60808901613976565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215613bf9578182fd5b613c028361385e565b946020939093013593505050565b600080600060608486031215613c24578081fd5b613c2d8461385e565b925060208401359150604084013567ffffffffffffffff811115613c4f578182fd5b613c5b868287016138d1565b9150509250925092565b600080600080600060a08688031215613c7c578283fd5b613c858661385e565b945060208601359350613c9a60408701613976565b94979396509394606081013594506080013592915050565b60008060008060408587031215613cc7578182fd5b843567ffffffffffffffff80821115613cde578384fd5b613cea88838901613887565b90965094506020870135915080821115613d02578384fd5b50613d0f87828801613887565b95989497509550505050565b600060208284031215613d2c578081fd5b5051919050565b600080600060608486031215613d47578081fd5b833567ffffffffffffffff80821115613d5e578283fd5b613d6a878388016138d1565b94506020860135915080821115613d7f578283fd5b50613d8c868287016138d1565b925050613d9b60408501613976565b90509250925092565b600060208284031215613db5578081fd5b5035919050565b60008151808452613dd4816020860160208601613e7d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251613e18818460208701613e7d565b9190910192915050565b828152604060208201526000610cca6040830184613dbc565b602081526000610ccd6020830184613dbc565b60008219821115613e6157613e61613f30565b500190565b600082821015613e7857613e78613f30565b500390565b60005b83811015613e98578181015183820152602001613e80565b83811115610a005750506000910152565b600181811c90821680613ebd57607f821691505b60208210811415613290577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613f2957613f29613f30565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea264697066735822122055b775390fed65f65a204ffd60a1e44c1b0072f387e3259284e9e28f6ad6c70b64736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102925760003560e01c806388b7ab6311610160578063cf092995116100d8578063e3ee160e1161008c578063ef55bec611610071578063ef55bec61461061a578063f2fde38b1461062d578063fbac39511461064057600080fd5b8063e3ee160e146105c0578063e94a0102146105d357600080fd5b8063d9169487116100bd578063d916948714610540578063db006a7514610567578063dd62ed3e1461057a57600080fd5b8063cf0929951461051a578063d505accf1461052d57600080fd5b80639fd5a6cf1161012f578063a457c2d711610114578063a457c2d7146104e1578063a9059cbb146104f4578063b7b728991461050757600080fd5b80639fd5a6cf146104a7578063a0cc6a68146104ba57600080fd5b806388b7ab63146104405780638da5cb5b1461045357806395d89b411461047b57806396d648791461048357600080fd5b80633644e5151161020e57806370a08231116101c257806379cc6790116101a757806379cc6790146103f35780637ecebe00146104065780637f2eecc31461041957600080fd5b806370a08231146103b5578063715018a6146103eb57600080fd5b80633c7c9b90116101f35780633c7c9b901461037c57806340c10f191461038f5780635a049a70146103a257600080fd5b80633644e51514610361578063395093511461036957600080fd5b806318160ddd116102655780631e89d5451161024a5780631e89d5451461032557806323b872dd14610338578063313ce5671461034b57600080fd5b806318160ddd146103005780631a14f4491461031257600080fd5b806306fdde0314610297578063095ea7b3146102b55780630e27a385146102d85780631624f6c6146102ed575b600080fd5b61029f610663565b6040516102ac9190613e3b565b60405180910390f35b6102c86102c3366004613be7565b6106f5565b60405190151581526020016102ac565b6102eb6102e6366004613987565b61070b565b005b6102eb6102fb366004613d33565b6108a4565b6035545b6040519081526020016102ac565b6102eb610320366004613987565b610a06565b6102eb610333366004613cb2565b610afb565b6102c86103463660046139d3565b610c45565b6101005460405160ff90911681526020016102ac565b610304610cd4565b6102c8610377366004613be7565b610ce3565b6102eb61038a366004613987565b610d2c565b6102eb61039d366004613be7565b610e24565b6102eb6103b0366004613c65565b610ef7565b6103046103c3366004613987565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b6102eb610f53565b6102eb610401366004613be7565b610fe0565b610304610414366004613987565b6110b3565b6103047fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b6102eb61044e366004613a7e565b6110e0565b60cc5460405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102ac565b61029f61117d565b6102c8610491366004613987565b60ff602081905260009182526040909120541681565b6102eb6104b5366004613a0e565b61118c565b6103047f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6102c86104ef366004613be7565b611199565b6102c8610502366004613be7565b611271565b6102eb610515366004613c10565b61127e565b6102eb610528366004613a7e565b61128e565b6102eb61053b366004613b7e565b611317565b6103047f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b6102eb610575366004613da4565b61137d565b6103046105883660046139a1565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b6102eb6105ce366004613b01565b61145c565b6102c86105e1366004613be7565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815261010160209081526040808320938352929052205460ff1690565b6102eb610628366004613b01565b611554565b6102eb61063b366004613987565b611636565b6102c861064e366004613987565b60fe6020526000908152604090205460ff1681565b60606036805461067290613ea9565b80601f016020809104026020016040519081016040528092919081815260200182805461069e90613ea9565b80156106eb5780601f106106c0576101008083540402835291602001916106eb565b820191906000526020600020905b8154815290600101906020018083116106ce57829003601f168201915b5050505050905090565b6000610702338484611766565b50600192915050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610791576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260fe602052604090205460ff16610820576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546574686572546f6b656e3a2075736572206973206e6f7420626c6f636b65646044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603360205260409020546108508282611919565b8173ffffffffffffffffffffffffffffffffffffffff167f6a2859ae7902313752498feb80a014e6e7275fe964c79aa965db815db1c7f1e98260405161089891815260200190565b60405180910390a25050565b600054610100900460ff16806108bd575060005460ff16155b610949576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff1615801561098857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61010080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff84161790556109be611b12565b6109c88484611c37565b6109d184611d60565b8015610a0057600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610a87576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f665918c9e02eb2fd85acca3969cb054fc84c138e60ec4af22ab6ef2fd4c93c279190a250565b828114610b8a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f546574686572546f6b656e3a206d756c74695472616e73666572206d69736d6160448201527f74636800000000000000000000000000000000000000000000000000000000006064820152608401610788565b60005b83811015610c3e57610c2b858583818110610bd1577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610be69190613987565b848484818110610c1f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135611271565b5080610c3681613ef7565b915050610b8d565b5050505050565b33600090815260fe602052604081205460ff1615610cbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b610cca848484611ec7565b90505b9392505050565b6000610cde611fad565b905090565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff871684529091528120549091610702918590610d27908690613e4e565b611766565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610dad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f406bbf2d8d145125adf1198d2cf8a67c66cc4bb0ab01c37dccd4f7c0aae1e7c79190a250565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610ea5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b610eaf8282612028565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d41213968858260405161089891815260200190565b60408051602081018490529081018290527fff0000000000000000000000000000000000000000000000000000000000000060f885901b166060820152610c3e9086908690606101604051602081830303815290604052612154565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610fd4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b610fde600061225a565b565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b61106b8282611919565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161089891815260200190565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120545b92915050565b33600090815260fe602052604090205460ff161561115a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b611169878787878787876122d1565b6111748787876123e2565b50505050505050565b60606037805461067290613ea9565b610c3e85858585856126a0565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120548281101561125a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610788565b6112673385858403611766565b5060019392505050565b60006107023384846123e2565b611289838383612154565b505050565b33600090815260fe602052604090205460ff1615611308576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b6111698787878787878761281f565b6111748787878786868960405160200161136993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b6040516020818303038152906040526126a0565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146113fe576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b61142661142060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b82611919565b6040518181527f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a449060200160405180910390a150565b33600090815260fe602052604090205460ff16156114d6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b61153e89898989898988888b60405160200161152a93929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b60405160208183030381529060405261281f565b6115498989896123e2565b505050505050505050565b33600090815260fe602052604090205460ff16156115ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b656400006044820152606401610788565b61153e89898989898988888b60405160200161162293929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b6040516020818303038152906040526122d1565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146116b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff811661175a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610788565b6117638161225a565b50565b73ffffffffffffffffffffffffffffffffffffffff8316611808576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff82166118ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff82166119bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610788565b6119c8826000836128a7565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015611a7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603360205260408120838303905560358054849290611aba908490613e66565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600054610100900460ff1680611b2b575060005460ff16155b611bb7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611bf657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611bfe6129ff565b611c06612b13565b801561176357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680611c50575060005460ff16155b611cdc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611d1b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611d236129ff565b611d2d8383612c00565b801561128957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680611d79575060005460ff16155b611e05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611e4457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611e4c6129ff565b611e8b826040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250612d3f565b611e9482612e73565b8015611ec357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b6000611ed48484846123e2565b73ffffffffffffffffffffffffffffffffffffffff8416600090815260346020908152604080832033845290915290205482811015611f95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e63650000000000000000000000000000000000000000000000006064820152608401610788565b611fa28533858403611766565b506001949350505050565b6000610cde7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f611fdc60655490565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b73ffffffffffffffffffffffffffffffffffffffff82166120a5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610788565b6120b1600083836128a7565b80603560008282546120c39190613e4e565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040812080548392906120fd908490613e4e565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b61215e8383612fad565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429602082015273ffffffffffffffffffffffffffffffffffffffff851691810191909152606081018390526121d39084906080015b6040516020818303038152906040528051906020012083613049565b73ffffffffffffffffffffffffffffffffffffffff831660008181526101016020908152604080832086845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b60cc805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b73ffffffffffffffffffffffffffffffffffffffff86163314612350576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546574686572546f6b656e3a20746f20213d206d73672e73656e6465720000006044820152606401610788565b61235c878386866130ff565b604080517fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526123d8908890610100016121b7565b61117487836131db565b73ffffffffffffffffffffffffffffffffffffffff8316612485576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff8216612528576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610788565b6125338383836128a7565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260336020526040902054818110156125e9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610788565b73ffffffffffffffffffffffffffffffffffffffff80851660009081526033602052604080822085850390559185168152908120805484929061262d908490613e4e565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8460405161269391815260200190565b60405180910390a3610a00565b8142111561270a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e650000006044820152606401610788565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c98686866127398a613261565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810184905260e00160405160208183030381529060405280519060200120905060006127a182613296565b90506127ae8782856132ff565b612814576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f454950323631323a20696e76616c6964207369676e61747572650000000000006044820152606401610788565b611174878787611766565b61282b878386866130ff565b604080517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526123d8908890610100016121b7565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260fe602052604090205460ff1615806128f3575060cc5473ffffffffffffffffffffffffffffffffffffffff1633145b612959576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546574686572546f6b656e3a2066726f6d20697320626c6f636b6564000000006044820152606401610788565b73ffffffffffffffffffffffffffffffffffffffff8216301415611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f546574686572546f6b656e3a207472616e7366657220746f2074686520636f6e60448201527f74726163742061646472657373000000000000000000000000000000000000006064820152608401610788565b600054610100900460ff1680612a18575060005460ff16155b612aa4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015611c0657600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000016610101179055801561176357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680612b2c575060005460ff16155b612bb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612bf757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b611c063361225a565b600054610100900460ff1680612c19575060005460ff16155b612ca5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612ce457600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8251612cf79060369060208601906137c5565b508151612d0b9060379060208501906137c5565b50801561128957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680612d58575060005460ff16155b612de4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612e2357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b8251602080850191909120835191840191909120606591909155606655801561128957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680612e8c575060005460ff16155b612f18576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a65640000000000000000000000000000000000006064820152608401610788565b600054610100900460ff16158015612f5757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a558015611ec357600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b73ffffffffffffffffffffffffffffffffffffffff821660009081526101016020908152604080832084845290915290205460ff1615611ec3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a206175746820696e76616c6964000000000000006044820152606401610788565b61309983613093613058610cd4565b856040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b836132ff565b611289576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546574686572546f6b656e3a20696e76616c6964207369676e617475726500006044820152606401610788565b814211613168576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546574686572546f6b656e3a2061757468206561726c790000000000000000006044820152606401610788565b8042106131d1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a20617574682065787069726564000000000000006044820152606401610788565b610a008484612fad565b73ffffffffffffffffffffffffffffffffffffffff821660008181526101016020908152604080832085845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006110da6132a3611fad565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000833b613346578373ffffffffffffffffffffffffffffffffffffffff166133288484613351565b73ffffffffffffffffffffffffffffffffffffffff16149050610ccd565b610cca84848461340c565b600081516041146133e4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45435265636f7665723a20696e76616c6964207369676e6174757265206c656e60448201527f67746800000000000000000000000000000000000000000000000000000000006064820152608401610788565b60208201516040830151606084015160001a61340286828585613569565b9695505050505050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b8686604051602401613443929190613e22565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009094169390931790925290516134cc9190613e06565b600060405180830381855afa9150503d8060008114613507576040519150601f19603f3d011682016040523d82523d6000602084013e61350c565b606091505b509150915081801561352057506020815110155b8015613402575080517f1626ba7e000000000000000000000000000000000000000000000000000000009061355e9083016020908101908401613d1b565b149695505050505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561361b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027732760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610788565b8360ff16601b1415801561363357508360ff16601c14155b156136c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027762760448201527f2076616c756500000000000000000000000000000000000000000000000000006064820152608401610788565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613714573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff81166137bc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45435265636f7665723a20696e76616c6964207369676e6174757265000000006044820152606401610788565b95945050505050565b8280546137d190613ea9565b90600052602060002090601f0160209004810192826137f35760008555613839565b82601f1061380c57805160ff1916838001178555613839565b82800160010185558215613839579182015b8281111561383957825182559160200191906001019061381e565b50613845929150613849565b5090565b5b80821115613845576000815560010161384a565b803573ffffffffffffffffffffffffffffffffffffffff8116811461388257600080fd5b919050565b60008083601f840112613898578081fd5b50813567ffffffffffffffff8111156138af578182fd5b6020830191508360208260051b85010111156138ca57600080fd5b9250929050565b600082601f8301126138e1578081fd5b813567ffffffffffffffff808211156138fc576138fc613f5f565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190828211818310171561394257613942613f5f565b8160405283815286602085880101111561395a578485fd5b8360208701602083013792830160200193909352509392505050565b803560ff8116811461388257600080fd5b600060208284031215613998578081fd5b610ccd8261385e565b600080604083850312156139b3578081fd5b6139bc8361385e565b91506139ca6020840161385e565b90509250929050565b6000806000606084860312156139e7578081fd5b6139f08461385e565b92506139fe6020850161385e565b9150604084013590509250925092565b600080600080600060a08688031215613a25578081fd5b613a2e8661385e565b9450613a3c6020870161385e565b93506040860135925060608601359150608086013567ffffffffffffffff811115613a65578182fd5b613a71888289016138d1565b9150509295509295909350565b600080600080600080600060e0888a031215613a98578182fd5b613aa18861385e565b9650613aaf6020890161385e565b955060408801359450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff811115613ae6578182fd5b613af28a828b016138d1565b91505092959891949750929550565b60008060008060008060008060006101208a8c031215613b1f578182fd5b613b288a61385e565b9850613b3660208b0161385e565b975060408a0135965060608a0135955060808a0135945060a08a01359350613b6060c08b01613976565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a031215613b98578283fd5b613ba18861385e565b9650613baf6020890161385e565b95506040880135945060608801359350613bcb60808901613976565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215613bf9578182fd5b613c028361385e565b946020939093013593505050565b600080600060608486031215613c24578081fd5b613c2d8461385e565b925060208401359150604084013567ffffffffffffffff811115613c4f578182fd5b613c5b868287016138d1565b9150509250925092565b600080600080600060a08688031215613c7c578283fd5b613c858661385e565b945060208601359350613c9a60408701613976565b94979396509394606081013594506080013592915050565b60008060008060408587031215613cc7578182fd5b843567ffffffffffffffff80821115613cde578384fd5b613cea88838901613887565b90965094506020870135915080821115613d02578384fd5b50613d0f87828801613887565b95989497509550505050565b600060208284031215613d2c578081fd5b5051919050565b600080600060608486031215613d47578081fd5b833567ffffffffffffffff80821115613d5e578283fd5b613d6a878388016138d1565b94506020860135915080821115613d7f578283fd5b50613d8c868287016138d1565b925050613d9b60408501613976565b90509250925092565b600060208284031215613db5578081fd5b5035919050565b60008151808452613dd4816020860160208601613e7d565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008251613e18818460208701613e7d565b9190910192915050565b828152604060208201526000610cca6040830184613dbc565b602081526000610ccd6020830184613dbc565b60008219821115613e6157613e61613f30565b500190565b600082821015613e7857613e78613f30565b500390565b60005b83811015613e98578181015183820152602001613e80565b83811115610a005750506000910152565b600181811c90821680613ebd57607f821691505b60208210811415613290577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613f2957613f29613f30565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea264697066735822122055b775390fed65f65a204ffd60a1e44c1b0072f387e3259284e9e28f6ad6c70b64736f6c63430008040033
Deployed Bytecode Sourcemap
65375:13380:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11876:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14043:169;;;;;;:::i;:::-;;:::i;:::-;;;10364:14:1;;10357:22;10339:41;;10327:2;10312:18;14043:169:0;10294:92:1;64672:321:0;;;;;;:::i;:::-;;:::i;:::-;;62823:281;;;;;;:::i;:::-;;:::i;12996:108::-;13084:12;;12996:108;;;10537:25:1;;;10525:2;10510:18;12996:108:0;10492:76:1;61980:143:0;;;;;;:::i;:::-;;:::i;63834:380::-;;;;;;:::i;:::-;;:::i;63588:238::-;;;;;;:::i;:::-;;:::i;63112:105::-;63195:14;;63112:105;;63195:14;;;;25165:36:1;;25153:2;25138:18;63112:105:0;25120:87:1;39465:115:0;;;:::i;15595:215::-;;;;;;:::i;:::-;;:::i;61837:135::-;;;;;;:::i;:::-;;:::i;64222:160::-;;;;;;:::i;:::-;;:::i;58111:237::-;;;;;;:::i;:::-;;:::i;13167:127::-;;;;;;:::i;:::-;13268:18;;13241:7;13268:18;;;:9;:18;;;;;;;13167:127;5099:94;;;:::i;64390:143::-;;;;;;:::i;:::-;;:::i;39207:128::-;;;;;;:::i;:::-;;:::i;53186:191::-;;53248:129;53186:191;;78213:505;;;;;;:::i;:::-;;:::i;4448:87::-;4521:6;;4448:87;;4521:6;;;;10114:74:1;;10102:2;10087:18;4448:87:0;10069:125:1;12095:104:0;;;:::i;62736:41::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;69781:238;;;;;;:::i;:::-;;:::i;52984:193::-;;53047:130;52984:193;;16313:413;;;;;;:::i;:::-;;:::i;13507:175::-;;;;;;:::i;:::-;;:::i;58755:200::-;;;;;;:::i;:::-;;:::i;73696:507::-;;;;;;:::i;:::-;;:::i;67993:294::-;;;;;;:::i;:::-;;:::i;53386:122::-;;53442:66;53386:122;;64541:123;;;;;;:::i;:::-;;:::i;13745:151::-;;;;;;:::i;:::-;13861:18;;;;13834:7;13861:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;13745:151;71573:546;;;;;;:::i;:::-;;:::i;54277:189::-;;;;;;:::i;:::-;54419:32;;;;;54390:4;54419:32;;;:20;:32;;;;;;;;:39;;;;;;;;;;;54277:189;75927:544;;;;;;:::i;:::-;;:::i;5348:192::-;;;;;;:::i;:::-;;:::i;61786:42::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;11876:100;11930:13;11963:5;11956:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11876:100;:::o;14043:169::-;14126:4;14143:39;2987:10;14166:7;14175:6;14143:8;:39::i;:::-;-1:-1:-1;14200:4:0;14043:169;;;;:::o;64672:321::-;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;;;;;;;;;64759:23:::1;::::0;::::1;;::::0;;;:9:::1;:23;::::0;;;;;::::1;;64751:68;;;::::0;::::1;::::0;;18564:2:1;64751:68:0::1;::::0;::::1;18546:21:1::0;;;18583:18;;;18576:30;18642:34;18622:18;;;18615:62;18694:18;;64751:68:0::1;18536:182:1::0;64751:68:0::1;13268:18:::0;;;64830:20:::1;13268:18:::0;;;:9;:18;;;;;;64887:33:::1;13268:18:::0;;64887:5:::1;:33::i;:::-;64958:12;64936:49;;;64972:12;64936:49;;;;10537:25:1::0;;10525:2;10510:18;;10492:76;64936:49:0::1;;;;;;;;4739:1;64672:321:::0;:::o;62823:281::-;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;62968:14:::1;:26:::0;;;::::1;;::::0;::::1;;::::0;;63005:16:::1;:14;:16::i;:::-;63032:28;63045:5;63052:7;63032:12;:28::i;:::-;63071:25;63090:5;63071:18;:25::i;:::-;1926:14:::0;1922:68;;;1973:5;1957:21;;;;;;1922:68;62823:281;;;;:::o;61980:143::-;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;21143:182:1;4660:68:0;62055:16:::1;::::0;::::1;62074:5;62055:16:::0;;;:9:::1;:16;::::0;;;;;:24;;;::::1;::::0;;62095:20;::::1;::::0;62074:5;62095:20:::1;61980:143:::0;:::o;63834:380::-;63985:36;;;63963:121;;;;;;;14657:2:1;63963:121:0;;;14639:21:1;14696:2;14676:18;;;14669:30;14735:34;14715:18;;;14708:62;14806:5;14786:18;;;14779:33;14829:19;;63963:121:0;14629:225:1;63963:121:0;64100:9;64095:112;64115:22;;;64095:112;;;64159:36;64168:11;;64180:1;64168:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;64184:7;;64192:1;64184:10;;;;;;;;;;;;;;;;;;;;;64159:8;:36::i;:::-;-1:-1:-1;64139:3:0;;;;:::i;:::-;;;;64095:112;;;;63834:380;;;;:::o;63588:238::-;2987:10;63746:4;61702:23;;;:9;:23;;;;;;;;61701:24;61693:67;;;;;;;23097:2:1;61693:67:0;;;23079:21:1;23136:2;23116:18;;;23109:30;23175:32;23155:18;;;23148:60;23225:18;;61693:67:0;23069:180:1;61693:67:0;63770:48:::1;63789:7;63798:10;63810:7;63770:18;:48::i;:::-;63763:55;;61769:1;63588:238:::0;;;;;:::o;39465:115::-;39525:7;39552:20;:18;:20::i;:::-;39545:27;;39465:115;:::o;15595:215::-;2987:10;15683:4;15732:25;;;:11;:25;;;;;;;;;:34;;;;;;;;;;15683:4;;15700:80;;15723:7;;15732:47;;15769:10;;15732:47;:::i;:::-;15700:8;:80::i;61837:135::-;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;21143:182:1;4660:68:0;61907:16:::1;::::0;::::1;;::::0;;;:9:::1;:16;::::0;;;;;:23;;;::::1;61926:4;61907:23;::::0;;61946:18;::::1;::::0;61907:16;61946:18:::1;61837:135:::0;:::o;64222:160::-;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;21143:182:1;4660:68:0;64303:28:::1;64309:12;64323:7;64303:5;:28::i;:::-;64352:12;64347:27;;;64366:7;64347:27;;;;10537:25:1::0;;10525:2;10510:18;;10492:76;58111:237:0;58316:23;;;;;;9025:19:1;;;9060:12;;;9053:28;;;9133:66;9119:3;9115:16;;;9111:89;9097:12;;;9090:111;58276:64:0;;58297:10;;58309:5;;9217:12:1;;58316:23:0;;;;;;;;;;;;58276:20;:64::i;5099:94::-;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;21143:182:1;4660:68:0;5164:21:::1;5182:1;5164:9;:21::i;:::-;5099:94::o:0;64390:143::-;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;21143:182:1;4660:68:0;64468:21:::1;64474:5;64481:7;64468:5;:21::i;:::-;64510:5;64505:20;;;64517:7;64505:20;;;;10537:25:1::0;;10525:2;10510:18;;10492:76;39207:128:0;39303:14;;;39276:7;39303:14;;;:7;:14;;;;;25243;39303:24;39296:31;39207:128;-1:-1:-1;;39207:128:0:o;78213:505::-;2987:10;61702:23;;;;:9;:23;;;;;;;;61701:24;61693:67;;;;;;;23097:2:1;61693:67:0;;;23079:21:1;23136:2;23116:18;;;23109:30;23175:32;23155:18;;;23148:60;23225:18;;61693:67:0;23069:180:1;61693:67:0;78473:200:::1;78526:4;78545:2;78562:5;78582:10;78607:11;78633:5;78653:9;78473:38;:200::i;:::-;78684:26;78694:4;78700:2;78704:5;78684:9;:26::i;:::-;78213:505:::0;;;;;;;:::o;12095:104::-;12151:13;12184:7;12177:14;;;;;:::i;69781:238::-;69959:52;69967:6;69975:7;69984:5;69991:8;70001:9;69959:7;:52::i;16313:413::-;2987:10;16406:4;16450:25;;;:11;:25;;;;;;;;;:34;;;;;;;;;;16503:35;;;;16495:85;;;;;;;24277:2:1;16495:85:0;;;24259:21:1;24316:2;24296:18;;;24289:30;24355:34;24335:18;;;24328:62;24426:7;24406:18;;;24399:35;24451:19;;16495:85:0;24249:227:1;16495:85:0;16616:67;2987:10;16639:7;16667:15;16648:16;:34;16616:8;:67::i;:::-;-1:-1:-1;16714:4:0;;16313:413;-1:-1:-1;;;16313:413:0:o;13507:175::-;13593:4;13610:42;2987:10;13634:9;13645:6;13610:9;:42::i;58755:200::-;58897:50;58918:10;58930:5;58937:9;58897:20;:50::i;:::-;58755:200;;;:::o;73696:507::-;2987:10;61702:23;;;;:9;:23;;;;;;;;61701:24;61693:67;;;;;;;23097:2:1;61693:67:0;;;23079:21:1;23136:2;23116:18;;;23109:30;23175:32;23155:18;;;23148:60;23225:18;;61693:67:0;23069:180:1;61693:67:0;73957:201:::1;74011:4;74030:2;74047:5;74067:10;74092:11;74118:5;74138:9;73957:39;:201::i;67993:294::-:0;68211:68;68219:6;68227:7;68236:5;68243:8;68270:1;68273;68276;68253:25;;;;;;;;;9025:19:1;;;9069:2;9060:12;;9053:28;;;;9119:3;9115:16;9133:66;9111:89;9106:2;9097:12;;9090:111;9226:2;9217:12;;9015:220;68253:25:0;;;;;;;;;;;;;68211:7;:68::i;64541:123::-;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;21143:182:1;4660:68:0;64602:23:::1;64608:7;4521:6:::0;;;;;4448:87;64608:7:::1;64617;64602:5;:23::i;:::-;64641:15;::::0;10537:25:1;;;64641:15:0::1;::::0;10525:2:1;10510:18;64641:15:0::1;;;;;;;64541:123:::0;:::o;71573:546::-;2987:10;61702:23;;;;:9;:23;;;;;;;;61701:24;61693:67;;;;;;;23097:2:1;61693:67:0;;;23079:21:1;23136:2;23116:18;;;23109:30;23175:32;23155:18;;;23148:60;23225:18;;61693:67:0;23069:180:1;61693:67:0;71857:217:::1;71911:4;71930:2;71947:5;71967:10;71992:11;72018:5;72055:1;72058;72061;72038:25;;;;;;;;;9025:19:1::0;;;9069:2;9060:12;;9053:28;;;;9119:3;9115:16;9133:66;9111:89;9106:2;9097:12;;9090:111;9226:2;9217:12;;9015:220;72038:25:0::1;;;;;;;;;;;;;71857:39;:217::i;:::-;72085:26;72095:4;72101:2;72105:5;72085:9;:26::i;:::-;71573:546:::0;;;;;;;;;:::o;75927:544::-;2987:10;61702:23;;;;:9;:23;;;;;;;;61701:24;61693:67;;;;;;;23097:2:1;61693:67:0;;;23079:21:1;23136:2;23116:18;;;23109:30;23175:32;23155:18;;;23148:60;23225:18;;61693:67:0;23069:180:1;61693:67:0;76210:216:::1;76263:4;76282:2;76299:5;76319:10;76344:11;76370:5;76407:1;76410;76413;76390:25;;;;;;;;;9025:19:1::0;;;9069:2;9060:12;;9053:28;;;;9119:3;9115:16;9133:66;9111:89;9106:2;9097:12;;9090:111;9226:2;9217:12;;9015:220;76390:25:0::1;;;;;;;;;;;;;76210:38;:216::i;5348:192::-:0;4521:6;;4668:23;4521:6;2987:10;4668:23;4660:68;;;;;;;21171:2:1;4660:68:0;;;21153:21:1;;;21190:18;;;21183:30;21249:34;21229:18;;;21222:62;21301:18;;4660:68:0;21143:182:1;4660:68:0;5437:22:::1;::::0;::::1;5429:73;;;::::0;::::1;::::0;;16634:2:1;5429:73:0::1;::::0;::::1;16616:21:1::0;16673:2;16653:18;;;16646:30;16712:34;16692:18;;;16685:62;16783:8;16763:18;;;16756:36;16809:19;;5429:73:0::1;16606:228:1::0;5429:73:0::1;5513:19;5523:8;5513:9;:19::i;:::-;5348:192:::0;:::o;19997:380::-;20133:19;;;20125:68;;;;;;;22692:2:1;20125:68:0;;;22674:21:1;22731:2;22711:18;;;22704:30;22770:34;22750:18;;;22743:62;22841:6;22821:18;;;22814:34;22865:19;;20125:68:0;22664:226:1;20125:68:0;20212:21;;;20204:68;;;;;;;17041:2:1;20204:68:0;;;17023:21:1;17080:2;17060:18;;;17053:30;17119:34;17099:18;;;17092:62;17190:4;17170:18;;;17163:32;17212:19;;20204:68:0;17013:224:1;20204:68:0;20285:18;;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;20337:32;;10537:25:1;;;20337:32:0;;10510:18:1;20337:32:0;;;;;;;19997:380;;;:::o;18968:591::-;19052:21;;;19044:67;;;;;;;21532:2:1;19044:67:0;;;21514:21:1;21571:2;21551:18;;;21544:30;21610:34;21590:18;;;21583:62;21681:3;21661:18;;;21654:31;21702:19;;19044:67:0;21504:223:1;19044:67:0;19124:49;19145:7;19162:1;19166:6;19124:20;:49::i;:::-;19211:18;;;19186:22;19211:18;;;:9;:18;;;;;;19248:24;;;;19240:71;;;;;;;15061:2:1;19240:71:0;;;15043:21:1;15100:2;15080:18;;;15073:30;15139:34;15119:18;;;15112:62;15210:4;15190:18;;;15183:32;15232:19;;19240:71:0;15033:224:1;19240:71:0;19347:18;;;;;;;:9;:18;;;;;19368:23;;;19347:44;;19413:12;:22;;19385:6;;19347:18;19413:22;;19385:6;;19413:22;:::i;:::-;;;;-1:-1:-1;;19453:37:0;;10537:25:1;;;19479:1:0;;19453:37;;;;;;10525:2:1;10510:18;19453:37:0;;;;;;;58755:200;;;:::o;4131:129::-;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;4189:26:::1;:24;:26::i;:::-;4226;:24;:26::i;:::-;1926:14:::0;1922:68;;;1973:5;1957:21;;;;;;4131:129;:::o;11460:181::-;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;11558:26:::1;:24;:26::i;:::-;11595:38;11618:5;11625:7;11595:22;:38::i;:::-;1926:14:::0;1922:68;;;1973:5;1957:21;;;;;;11460:181;;;:::o;38001:204::-;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;38081:26:::1;:24;:26::i;:::-;38118:34;38142:4;38118:34;;;;;;;;;;;;;;;;::::0;:23:::1;:34::i;:::-;38163;38192:4;38163:28;:34::i;:::-;1926:14:::0;1922:68;;;1973:5;1957:21;;;;;;1922:68;38001:204;;:::o;14694:492::-;14834:4;14851:36;14861:6;14869:9;14880:6;14851:9;:36::i;:::-;14927:19;;;14900:24;14927:19;;;:11;:19;;;;;;;;2987:10;14927:33;;;;;;;;14979:26;;;;14971:79;;;;;;;20762:2:1;14971:79:0;;;20744:21:1;20801:2;20781:18;;;20774:30;20840:34;20820:18;;;20813:62;20911:10;20891:18;;;20884:38;20939:19;;14971:79:0;20734:230:1;14971:79:0;15086:57;15095:6;2987:10;15136:6;15117:16;:25;15086:8;:57::i;:::-;-1:-1:-1;15174:4:0;;14694:492;-1:-1:-1;;;;14694:492:0:o;34683:162::-;34736:7;34763:74;33416:95;34797:17;36265:12;;;36180:105;34797:17;36620:15;;35034:73;;;;;;12515:25:1;;;12556:18;;;12549:34;;;12599:18;;;12592:34;;;35078:13:0;12642:18:1;;;12635:34;35101:4:0;12685:19:1;;;12678:84;34997:7:0;;12487:19:1;;35034:73:0;;;;;;;;;;;;35024:84;;;;;;35017:91;;34853:263;;;;;;18236:399;18320:21;;;18312:65;;;;;;;24683:2:1;18312:65:0;;;24665:21:1;24722:2;24702:18;;;24695:30;24761:33;24741:18;;;24734:61;24812:18;;18312:65:0;24655:181:1;18312:65:0;18390:49;18419:1;18423:7;18432:6;18390:20;:49::i;:::-;18468:6;18452:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;18485:18:0;;;;;;;:9;:18;;;;;:28;;18507:6;;18485:18;:28;;18507:6;;18485:28;:::i;:::-;;;;-1:-1:-1;;18529:37:0;;10537:25:1;;;18529:37:0;;;;18546:1;;18529:37;;10525:2:1;10510:18;18529:37:0;;;;;;;38001:204;;:::o;57261:523::-;57404:46;57432:10;57444:5;57404:27;:46::i;:::-;57551:60;;;53442:66;57551:60;;;12085:25:1;12158:42;12146:55;;12126:18;;;12119:83;;;;12218:18;;;12211:34;;;57461:200:0;;57498:10;;12058:18:1;;57551:60:0;;;;;;;;;;;;;57523:103;;;;;;57641:9;57461:22;:200::i;:::-;57674:32;;;;;;;:20;:32;;;;;;;;:39;;;;;;;;;:46;;;;57716:4;57674:46;;;57736:40;57707:5;;57674:32;57736:40;;;57261:523;;;:::o;5548:173::-;5623:6;;;;5640:17;;;;;;;;;;;5673:40;;5623:6;;;5640:17;5623:6;;5673:40;;5604:16;;5673:40;5548:173;;:::o;56396:857::-;56663:16;;;56669:10;56663:16;56655:58;;;;;;;14299:2:1;56655:58:0;;;14281:21:1;14338:2;14318:18;;;14311:30;14377:31;14357:18;;;14350:59;14426:18;;56655:58:0;14271:179:1;56655:58:0;56724:64;56751:4;56757:5;56764:10;56776:11;56724:26;:64::i;:::-;56883:262;;;53248:129;56883:262;;;11507:25:1;11551:42;11629:15;;;11609:18;;;11602:43;;;;11681:15;;;11661:18;;;11654:43;11713:18;;;11706:34;;;11756:19;;;11749:35;;;11800:19;;;11793:35;;;11844:19;;;11837:35;;;56799:396:0;;56836:4;;11479:19:1;;56883:262:0;11461:417:1;56799:396:0;57208:37;57233:4;57239:5;57208:24;:37::i;17216:733::-;17356:20;;;17348:70;;;;;;;21934:2:1;17348:70:0;;;21916:21:1;21973:2;21953:18;;;21946:30;22012:34;21992:18;;;21985:62;22083:7;22063:18;;;22056:35;22108:19;;17348:70:0;21906:227:1;17348:70:0;17437:23;;;17429:71;;;;;;;13895:2:1;17429:71:0;;;13877:21:1;13934:2;13914:18;;;13907:30;13973:34;13953:18;;;13946:62;14044:5;14024:18;;;14017:33;14067:19;;17429:71:0;13867:225:1;17429:71:0;17513:47;17534:6;17542:9;17553:6;17513:20;:47::i;:::-;17597:17;;;17573:21;17597:17;;;:9;:17;;;;;;17633:23;;;;17625:74;;;;;;;17802:2:1;17625:74:0;;;17784:21:1;17841:2;17821:18;;;17814:30;17880:34;17860:18;;;17853:62;17951:8;17931:18;;;17924:36;17977:19;;17625:74:0;17774:228:1;17625:74:0;17735:17;;;;;;;;:9;:17;;;;;;17755:22;;;17735:42;;17799:20;;;;;;;;:30;;17771:6;;17735:17;17799:30;;17771:6;;17799:30;:::i;:::-;;;;;;;;17864:9;17847:35;;17856:6;17847:35;;;17875:6;17847:35;;;;10537:25:1;;10525:2;10510:18;;10492:76;17847:35:0;;;;;;;;17895:46;58755:200;66795:774;67001:8;66982:15;:27;;66974:69;;;;;;;17444:2:1;66974:69:0;;;17426:21:1;17483:2;17463:18;;;17456:30;17522:31;17502:18;;;17495:59;17571:18;;66974:69:0;17416:179:1;66974:69:0;67056:18;65483:119;67165:6;67190:7;67216:5;67240:17;67250:6;67240:9;:17::i;:::-;67101:198;;;;;;10860:25:1;;;;10904:42;10982:15;;;10962:18;;;10955:43;11034:15;;;;11014:18;;;11007:43;11066:18;;;11059:34;11109:19;;;11102:35;11153:19;;;11146:35;;;10832:19;;67101:198:0;;;;;;;;;;;;67077:233;;;;;;67056:254;;67323:12;67338:28;67355:10;67338:16;:28::i;:::-;67323:43;;67401:61;67438:6;67446:4;67452:9;67401:36;:61::i;:::-;67379:137;;;;;;;18209:2:1;67379:137:0;;;18191:21:1;18248:2;18228:18;;;18221:30;18287:28;18267:18;;;18260:56;18333:18;;67379:137:0;18181:176:1;67379:137:0;67529:32;67538:6;67546:7;67555:5;67529:8;:32::i;54951:790::-;55211:64;55238:4;55244:5;55251:10;55263:11;55211:26;:64::i;:::-;55370:263;;;53047:130;55370:263;;;11507:25:1;11551:42;11629:15;;;11609:18;;;11602:43;;;;11681:15;;;11661:18;;;11654:43;11713:18;;;11706:34;;;11756:19;;;11749:35;;;11800:19;;;11793:35;;;11844:19;;;11837:35;;;55286:397:0;;55323:4;;11479:19:1;;55370:263:0;11461:417:1;63225:355:0;63370:15;;;;;;;:9;:15;;;;;;;;63369:16;;:41;;-1:-1:-1;4521:6:0;;;;63389:10;:21;63369:41;63361:82;;;;;;;19697:2:1;63361:82:0;;;19679:21:1;19736:2;19716:18;;;19709:30;19775;19755:18;;;19748:58;19823:18;;63361:82:0;19669:178:1;63361:82:0;63477:19;;;63491:4;63477:19;;63454:117;;;;;;;23863:2:1;63454:117:0;;;23845:21:1;23902:2;23882:18;;;23875:30;23941:34;23921:18;;;23914:62;24012:15;23992:18;;;23985:43;24045:19;;63454:117:0;23835:235:1;2836:65:0;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1922:68;;;;1973:5;1957:21;;;;;;2836:65;:::o;4268:99::-;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;4336:23:::1;2987:10:::0;4336:9:::1;:23::i;11649:157::-:0;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;11757:13;;::::1;::::0;:5:::1;::::0;:13:::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;11781:17:0;;::::1;::::0;:7:::1;::::0;:17:::1;::::0;::::1;::::0;::::1;:::i;:::-;;1926:14:::0;1922:68;;;1973:5;1957:21;;;;;;11649:157;;;:::o;34295:297::-;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;34424:22;;::::1;::::0;;::::1;::::0;;;;34481:25;;;;::::1;::::0;;;;34517:12:::1;:25:::0;;;;34553:15:::1;:31:::0;1922:68;;;;1973:5;1957:21;;;;;;34295:297;;;:::o;38213:206::-;1654:13;;;;;;;;:30;;-1:-1:-1;1672:12:0;;;;1671:13;1654:30;1646:89;;;;;;;19282:2:1;1646:89:0;;;19264:21:1;19321:2;19301:18;;;19294:30;19360:34;19340:18;;;19333:62;19431:16;19411:18;;;19404:44;19465:19;;1646:89:0;19254:236:1;1646:89:0;1748:19;1771:13;;;;;;1770:14;1795:101;;;;1830:13;:20;;1865:19;;;;;;1795:101;38322:95:::1;38303:16;:114:::0;1922:68;;;;1973:5;1957:21;;;;;;38213:206;;:::o;59801:242::-;59943:32;;;;;;;:20;:32;;;;;;;;:39;;;;;;;;;;;59942:40;59920:115;;;;;;;20054:2:1;59920:115:0;;;20036:21:1;20093:2;20073:18;;;20066:30;20132:27;20112:18;;;20105:55;20177:18;;59920:115:0;20026:175:1;59195:420:0;59365:184;59420:6;59445:61;59478:17;:15;:17::i;:::-;59497:8;42247:4;42241:11;42278:10;42266:23;;42319:4;42310:14;;42303:39;;;;42372:4;42363:14;;42356:34;42429:4;42414:20;;;42215:230;59445:61;59525:9;59365:36;:184::i;:::-;59343:264;;;;;;;15868:2:1;59343:264:0;;;15850:21:1;15907:2;15887:18;;;15880:30;15946:32;15926:18;;;15919:60;15996:18;;59343:264:0;15840:180:1;60378:423:0;60597:10;60579:15;:28;60557:101;;;;;;;22340:2:1;60557:101:0;;;22322:21:1;22379:2;22359:18;;;22352:30;22418:25;22398:18;;;22391:53;22461:18;;60557:101:0;22312:173:1;60557:101:0;60695:11;60677:15;:29;60669:67;;;;;;;20408:2:1;60669:67:0;;;20390:21:1;20447:2;20427:18;;;20420:30;20486:27;20466:18;;;20459:55;20531:18;;60669:67:0;20380:175:1;60669:67:0;60747:46;60775:10;60787:5;60747:27;:46::i;60979:208::-;61081:32;;;;;;;:20;:32;;;;;;;;:39;;;;;;;;;:46;;;;61123:4;61081:46;;;61143:36;61114:5;;61081:32;61143:36;;;60979:208;;:::o;39718:218::-;39850:14;;;39778:15;39850:14;;;:7;:14;;;;;25243;;25380:1;25362:19;;;;25243:14;39911:17;39718:218;;;;:::o;35758:178::-;35835:7;35862:66;35895:20;:18;:20::i;:::-;35917:10;31779:57;;9789:66:1;31779:57:0;;;9777:79:1;9872:11;;;9865:27;;;9908:12;;;9901:28;;;31742:7:0;;9945:12:1;;31779:57:0;;;;;;;;;;;;31769:68;;;;;;31762:75;;31649:196;;;;;50020:342;50162:4;51765:17;;50179:105;;50266:6;50226:46;;:36;50244:6;50252:9;50226:17;:36::i;:::-;:46;;;50219:53;;;;50179:105;50301:53;50328:6;50336;50344:9;50301:26;:53::i;47558:661::-;47665:7;47698:9;:16;47718:2;47698:22;47690:70;;;;;;;15464:2:1;47690:70:0;;;15446:21:1;15503:2;15483:18;;;15476:30;15542:34;15522:18;;;15515:62;15613:5;15593:18;;;15586:33;15636:19;;47690:70:0;15436:225:1;47690:70:0;48052:4;48037:20;;48031:27;48098:4;48083:20;;48077:27;48152:4;48137:20;;48131:27;47773:9;48123:36;48187:24;48195:6;48123:36;48031:27;48077;48187:7;:24::i;:::-;48180:31;47558:661;-1:-1:-1;;;;;;47558:661:0:o;50981:567::-;51130:4;51148:12;51162:19;51185:6;:17;;51258:34;;;51311:6;51336:9;51217:143;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51185:186;;;;51217:143;51185:186;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51147:224;;;;51390:7;:43;;;;;51431:2;51414:6;:13;:19;;51390:43;:149;;;;-1:-1:-1;51450:29:0;;51504:34;;51450:29;;;;;;;;;;;;:::i;:::-;:89;51382:158;50981:567;-1:-1:-1;;;;;;50981:567:0:o;45547:1587::-;45677:7;46624:66;46598:92;;46580:197;;;46717:48;;;;;23456:2:1;46717:48:0;;;23438:21:1;23495:2;23475:18;;;23468:30;23534:34;23514:18;;;23507:62;23605:8;23585:18;;;23578:36;23631:19;;46717:48:0;23428:228:1;46580:197:0;46793:1;:7;;46798:2;46793:7;;:18;;;;;46804:1;:7;;46809:2;46804:7;;46793:18;46789:99;;;46828:48;;;;;16227:2:1;46828:48:0;;;16209:21:1;16266:2;16246:18;;;16239:30;16305:34;16285:18;;;16278:62;16376:8;16356:18;;;16349:36;16402:19;;46828:48:0;16199:228:1;46789:99:0;47002:26;;;46985:14;47002:26;;;;;;;;;13293:25:1;;;13366:4;13354:17;;13334:18;;;13327:45;;;;13388:18;;;13381:34;;;13431:18;;;13424:34;;;47002:26:0;;13265:19:1;;47002:26:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47002:26:0;;;;;;-1:-1:-1;;47047:20:0;;;47039:61;;;;;;;18925:2:1;47039:61:0;;;18907:21:1;18964:2;18944:18;;;18937:30;19003;18983:18;;;18976:58;19051:18;;47039:61:0;18897:178:1;47039:61:0;47120:6;45547:1587;-1:-1:-1;;;;;45547:1587:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:196:1;82:20;;142:42;131:54;;121:65;;111:2;;200:1;197;190:12;111:2;63:147;;;:::o;215:391::-;278:8;288:6;342:3;335:4;327:6;323:17;319:27;309:2;;365:6;357;350:22;309:2;-1:-1:-1;393:20:1;;436:18;425:30;;422:2;;;475:8;465;458:26;422:2;519:4;511:6;507:17;495:29;;579:3;572:4;562:6;559:1;555:14;547:6;543:27;539:38;536:47;533:2;;;596:1;593;586:12;533:2;299:307;;;;;:::o;611:797::-;653:5;706:3;699:4;691:6;687:17;683:27;673:2;;728:5;721;714:20;673:2;768:6;755:20;794:18;831:2;827;824:10;821:2;;;837:18;;:::i;:::-;971:2;965:9;1033:4;1025:13;;876:66;1021:22;;;1045:2;1017:31;1013:40;1001:53;;;1069:18;;;1089:22;;;1066:46;1063:2;;;1115:18;;:::i;:::-;1155:10;1151:2;1144:22;1190:2;1182:6;1175:18;1236:3;1229:4;1224:2;1216:6;1212:15;1208:26;1205:35;1202:2;;;1257:5;1250;1243:20;1202:2;1325;1318:4;1310:6;1306:17;1299:4;1291:6;1287:17;1274:54;1348:15;;;1365:4;1344:26;1337:41;;;;-1:-1:-1;1352:6:1;663:745;-1:-1:-1;;;663:745:1:o;1413:156::-;1479:20;;1539:4;1528:16;;1518:27;;1508:2;;1559:1;1556;1549:12;1574:196;1633:6;1686:2;1674:9;1665:7;1661:23;1657:32;1654:2;;;1707:6;1699;1692:22;1654:2;1735:29;1754:9;1735:29;:::i;1775:270::-;1843:6;1851;1904:2;1892:9;1883:7;1879:23;1875:32;1872:2;;;1925:6;1917;1910:22;1872:2;1953:29;1972:9;1953:29;:::i;:::-;1943:39;;2001:38;2035:2;2024:9;2020:18;2001:38;:::i;:::-;1991:48;;1862:183;;;;;:::o;2050:338::-;2127:6;2135;2143;2196:2;2184:9;2175:7;2171:23;2167:32;2164:2;;;2217:6;2209;2202:22;2164:2;2245:29;2264:9;2245:29;:::i;:::-;2235:39;;2293:38;2327:2;2316:9;2312:18;2293:38;:::i;:::-;2283:48;;2378:2;2367:9;2363:18;2350:32;2340:42;;2154:234;;;;;:::o;2393:626::-;2497:6;2505;2513;2521;2529;2582:3;2570:9;2561:7;2557:23;2553:33;2550:2;;;2604:6;2596;2589:22;2550:2;2632:29;2651:9;2632:29;:::i;:::-;2622:39;;2680:38;2714:2;2703:9;2699:18;2680:38;:::i;:::-;2670:48;;2765:2;2754:9;2750:18;2737:32;2727:42;;2816:2;2805:9;2801:18;2788:32;2778:42;;2871:3;2860:9;2856:19;2843:33;2899:18;2891:6;2888:30;2885:2;;;2936:6;2928;2921:22;2885:2;2964:49;3005:7;2996:6;2985:9;2981:22;2964:49;:::i;:::-;2954:59;;;2540:479;;;;;;;;:::o;3024:764::-;3146:6;3154;3162;3170;3178;3186;3194;3247:3;3235:9;3226:7;3222:23;3218:33;3215:2;;;3269:6;3261;3254:22;3215:2;3297:29;3316:9;3297:29;:::i;:::-;3287:39;;3345:38;3379:2;3368:9;3364:18;3345:38;:::i;:::-;3335:48;;3430:2;3419:9;3415:18;3402:32;3392:42;;3481:2;3470:9;3466:18;3453:32;3443:42;;3532:3;3521:9;3517:19;3504:33;3494:43;;3584:3;3573:9;3569:19;3556:33;3546:43;;3640:3;3629:9;3625:19;3612:33;3668:18;3660:6;3657:30;3654:2;;;3705:6;3697;3690:22;3654:2;3733:49;3774:7;3765:6;3754:9;3750:22;3733:49;:::i;:::-;3723:59;;;3205:583;;;;;;;;;;:::o;3793:754::-;3922:6;3930;3938;3946;3954;3962;3970;3978;3986;4039:3;4027:9;4018:7;4014:23;4010:33;4007:2;;;4061:6;4053;4046:22;4007:2;4089:29;4108:9;4089:29;:::i;:::-;4079:39;;4137:38;4171:2;4160:9;4156:18;4137:38;:::i;:::-;4127:48;;4222:2;4211:9;4207:18;4194:32;4184:42;;4273:2;4262:9;4258:18;4245:32;4235:42;;4324:3;4313:9;4309:19;4296:33;4286:43;;4376:3;4365:9;4361:19;4348:33;4338:43;;4400:37;4432:3;4421:9;4417:19;4400:37;:::i;:::-;4390:47;;4484:3;4473:9;4469:19;4456:33;4446:43;;4536:3;4525:9;4521:19;4508:33;4498:43;;3997:550;;;;;;;;;;;:::o;4552:616::-;4663:6;4671;4679;4687;4695;4703;4711;4764:3;4752:9;4743:7;4739:23;4735:33;4732:2;;;4786:6;4778;4771:22;4732:2;4814:29;4833:9;4814:29;:::i;:::-;4804:39;;4862:38;4896:2;4885:9;4881:18;4862:38;:::i;:::-;4852:48;;4947:2;4936:9;4932:18;4919:32;4909:42;;4998:2;4987:9;4983:18;4970:32;4960:42;;5021:37;5053:3;5042:9;5038:19;5021:37;:::i;:::-;5011:47;;5105:3;5094:9;5090:19;5077:33;5067:43;;5157:3;5146:9;5142:19;5129:33;5119:43;;4722:446;;;;;;;;;;:::o;5173:264::-;5241:6;5249;5302:2;5290:9;5281:7;5277:23;5273:32;5270:2;;;5323:6;5315;5308:22;5270:2;5351:29;5370:9;5351:29;:::i;:::-;5341:39;5427:2;5412:18;;;;5399:32;;-1:-1:-1;;;5260:177:1:o;5442:482::-;5528:6;5536;5544;5597:2;5585:9;5576:7;5572:23;5568:32;5565:2;;;5618:6;5610;5603:22;5565:2;5646:29;5665:9;5646:29;:::i;:::-;5636:39;;5722:2;5711:9;5707:18;5694:32;5684:42;;5777:2;5766:9;5762:18;5749:32;5804:18;5796:6;5793:30;5790:2;;;5841:6;5833;5826:22;5790:2;5869:49;5910:7;5901:6;5890:9;5886:22;5869:49;:::i;:::-;5859:59;;;5555:369;;;;;:::o;5929:472::-;6022:6;6030;6038;6046;6054;6107:3;6095:9;6086:7;6082:23;6078:33;6075:2;;;6129:6;6121;6114:22;6075:2;6157:29;6176:9;6157:29;:::i;:::-;6147:39;;6233:2;6222:9;6218:18;6205:32;6195:42;;6256:36;6288:2;6277:9;6273:18;6256:36;:::i;:::-;6065:336;;;;-1:-1:-1;6246:46:1;;6339:2;6324:18;;6311:32;;-1:-1:-1;6390:3:1;6375:19;6362:33;;6065:336;-1:-1:-1;;6065:336:1:o;6675:803::-;6797:6;6805;6813;6821;6874:2;6862:9;6853:7;6849:23;6845:32;6842:2;;;6895:6;6887;6880:22;6842:2;6940:9;6927:23;6969:18;7010:2;7002:6;6999:14;6996:2;;;7031:6;7023;7016:22;6996:2;7075:70;7137:7;7128:6;7117:9;7113:22;7075:70;:::i;:::-;7164:8;;-1:-1:-1;7049:96:1;-1:-1:-1;7252:2:1;7237:18;;7224:32;;-1:-1:-1;7268:16:1;;;7265:2;;;7302:6;7294;7287:22;7265:2;;7346:72;7410:7;7399:8;7388:9;7384:24;7346:72;:::i;:::-;6832:646;;;;-1:-1:-1;7437:8:1;-1:-1:-1;;;;6832:646:1:o;7483:194::-;7553:6;7606:2;7594:9;7585:7;7581:23;7577:32;7574:2;;;7627:6;7619;7612:22;7574:2;-1:-1:-1;7655:16:1;;7564:113;-1:-1:-1;7564:113:1:o;7682:641::-;7777:6;7785;7793;7846:2;7834:9;7825:7;7821:23;7817:32;7814:2;;;7867:6;7859;7852:22;7814:2;7912:9;7899:23;7941:18;7982:2;7974:6;7971:14;7968:2;;;8003:6;7995;7988:22;7968:2;8031:49;8072:7;8063:6;8052:9;8048:22;8031:49;:::i;:::-;8021:59;;8133:2;8122:9;8118:18;8105:32;8089:48;;8162:2;8152:8;8149:16;8146:2;;;8183:6;8175;8168:22;8146:2;;8211:51;8254:7;8243:8;8232:9;8228:24;8211:51;:::i;:::-;8201:61;;;8281:36;8313:2;8302:9;8298:18;8281:36;:::i;:::-;8271:46;;7804:519;;;;;:::o;8328:190::-;8387:6;8440:2;8428:9;8419:7;8415:23;8411:32;8408:2;;;8461:6;8453;8446:22;8408:2;-1:-1:-1;8489:23:1;;8398:120;-1:-1:-1;8398:120:1:o;8523:316::-;8564:3;8602:5;8596:12;8629:6;8624:3;8617:19;8645:63;8701:6;8694:4;8689:3;8685:14;8678:4;8671:5;8667:16;8645:63;:::i;:::-;8753:2;8741:15;8758:66;8737:88;8728:98;;;;8828:4;8724:109;;8572:267;-1:-1:-1;;8572:267:1:o;9240:274::-;9369:3;9407:6;9401:13;9423:53;9469:6;9464:3;9457:4;9449:6;9445:17;9423:53;:::i;:::-;9492:16;;;;;9377:137;-1:-1:-1;;9377:137:1:o;12773:288::-;12948:6;12937:9;12930:25;12991:2;12986;12975:9;12971:18;12964:30;12911:4;13011:44;13051:2;13040:9;13036:18;13028:6;13011:44;:::i;13469:219::-;13618:2;13607:9;13600:21;13581:4;13638:44;13678:2;13667:9;13663:18;13655:6;13638:44;:::i;25212:128::-;25252:3;25283:1;25279:6;25276:1;25273:13;25270:2;;;25289:18;;:::i;:::-;-1:-1:-1;25325:9:1;;25260:80::o;25345:125::-;25385:4;25413:1;25410;25407:8;25404:2;;;25418:18;;:::i;:::-;-1:-1:-1;25455:9:1;;25394:76::o;25475:258::-;25547:1;25557:113;25571:6;25568:1;25565:13;25557:113;;;25647:11;;;25641:18;25628:11;;;25621:39;25593:2;25586:10;25557:113;;;25688:6;25685:1;25682:13;25679:2;;;-1:-1:-1;;25723:1:1;25705:16;;25698:27;25528:205::o;25738:437::-;25817:1;25813:12;;;;25860;;;25881:2;;25935:4;25927:6;25923:17;25913:27;;25881:2;25988;25980:6;25977:14;25957:18;25954:38;25951:2;;;26025:77;26022:1;26015:88;26126:4;26123:1;26116:15;26154:4;26151:1;26144:15;26180:195;26219:3;26250:66;26243:5;26240:77;26237:2;;;26320:18;;:::i;:::-;-1:-1:-1;26367:1:1;26356:13;;26227:148::o;26380:184::-;26432:77;26429:1;26422:88;26529:4;26526:1;26519:15;26553:4;26550:1;26543:15;26569:184;26621:77;26618:1;26611:88;26718:4;26715:1;26708:15;26742:4;26739:1;26732:15
Swarm Source
ipfs://55b775390fed65f65a204ffd60a1e44c1b0072f387e3259284e9e28f6ad6c70b
Loading...
Loading
Loading...
Loading
Multichain Portfolio | 31 Chains
Chain | Token | Portfolio % | Price | Amount | Value |
---|
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.