Source Code
Overview
ETH Balance
0 ETH
ETH Value
$0.00View more zero value Internal Transactions in Advanced View mode
Advanced mode:
Cross-Chain Transactions
Loading...
Loading
Contract Name:
TetherTokenOFTExtension
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 100000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.4;
import "contracts/Tether/TetherTokenV2.sol";
import {IERC7802, IERC165} from "contracts/Wrappers/interfaces/IERC7802.sol";
/*
Copyright USDT0 2025
Author Will Norden
Licensed under the Apache License, Version 2.0
http://www.apache.org/licenses/LICENSE-2.0
*/
contract TetherTokenOFTExtension is TetherTokenV2, IERC7802 {
event LogSetOFTContract(address indexed oftContract);
event Burn(address indexed from, uint256 amount);
event LogUpdateNameAndSymbol(string name, string symbol);
address public oftContract;
string internal _newName;
string internal _newSymbol;
modifier onlyAuthorizedSender() {
require(msg.sender == oftContract, "Only OFT can call");
_;
}
function crosschainMint(address _destination, uint256 _amount) public override onlyAuthorizedSender {
_mint(_destination, _amount);
emit Mint(_destination, _amount);
emit CrosschainMint(_destination, _amount, msg.sender);
}
function crosschainBurn(address _from, uint256 _amount) public override onlyAuthorizedSender {
_burn(_from, _amount);
emit Burn(_from, _amount);
emit CrosschainBurn(_from, _amount, msg.sender);
}
function setOFTContract(address _oftContract) external onlyOwner {
oftContract = _oftContract;
emit LogSetOFTContract(_oftContract);
}
/**
* @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 override view returns (bytes32) {
return keccak256(bytes(name()));
}
function updateNameAndSymbol(string memory _name, string memory _symbol) public onlyOwner {
_newName = _name;
_newSymbol = _symbol;
emit LogUpdateNameAndSymbol(_name, _symbol);
}
/**
* @dev Returns the name of the token.
*/
function name() public view virtual override returns (string memory) {
return bytes(_newName).length == 0 ? super.name() : _newName;
}
/**
* @dev Returns the symbol of the token, usually a shorter version of the
* name.
*/
function symbol() public view virtual override returns (string memory) {
return bytes(_newSymbol).length == 0 ? super.symbol() : _newSymbol;
}
function supportsInterface(bytes4 interfaceId) external pure override returns (bool) {
return interfaceId == type(IERC7802).interfaceId || interfaceId == type(IERC165).interfaceId;
}
uint256[47] private __gap;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../utils/ContextUpgradeable.sol";
import "../proxy/utils/Initializable.sol";
/**
* @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;
}// 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;
}
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./IERC20Upgradeable.sol";
import "./extensions/IERC20MetadataUpgradeable.sol";
import "../../utils/ContextUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the {IERC20} interface.
*
* This implementation is agnostic to the way tokens are created. This means
* that a supply mechanism has to be added in a derived contract using {_mint}.
* For a generic mechanism see {ERC20PresetMinterPauser}.
*
* TIP: For a detailed writeup see our guide
* https://forum.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;
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./draft-IERC20PermitUpgradeable.sol";
import "../ERC20Upgradeable.sol";
import "../../../utils/cryptography/draft-EIP712Upgradeable.sol";
import "../../../utils/cryptography/ECDSAUpgradeable.sol";
import "../../../utils/CountersUpgradeable.sol";
import "../../../proxy/utils/Initializable.sol";
/**
* @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
* https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
*
* Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
* presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
* need to send a transaction, and thus is not required to hold Ether at all.
*
* _Available since v3.4._
*/
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;
}// 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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../IERC20Upgradeable.sol";
/**
* @dev Interface for the optional metadata functions from the ERC20 standard.
*
* _Available since v4.1._
*/
interface IERC20MetadataUpgradeable is IERC20Upgradeable {
/**
* @dev Returns the name of the token.
*/
function name() external view returns (string memory);
/**
* @dev Returns the symbol of the token.
*/
function symbol() external view returns (string memory);
/**
* @dev Returns the decimals places of the token.
*/
function decimals() external view returns (uint8);
}// 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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../proxy/utils/Initializable.sol";
/*
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract ContextUpgradeable is Initializable {
function __Context_init() internal 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;
}// 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;
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "./ECDSAUpgradeable.sol";
import "../../proxy/utils/Initializable.sol";
/**
* @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
*
* The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
* thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
* they need in their contracts using a combination of `abi.encode` and `keccak256`.
*
* This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
* scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
* ({_hashTypedDataV4}).
*
* The implementation of the domain separator was designed to be as efficient as possible while still properly updating
* the chain id to protect against replay attacks on an eventual fork of the chain.
*
* NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
* https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
*
* _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;
}// 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));
}
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @dev Interface of the ERC165 standard, as defined in the
* https://eips.ethereum.org/EIPS/eip-165[EIP].
*
* Implementers can declare support of contract interfaces, which can then be
* queried by others ({ERC165Checker}).
*
* For an implementation, see {ERC165}.
*/
interface IERC165 {
/**
* @dev Returns true if this contract implements the interface defined by
* `interfaceId`. See the corresponding
* https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
* to learn more about how these ids are created.
*
* This function call must use less than 30 000 gas.
*/
function supportsInterface(bytes4 interfaceId) external view returns (bool);
}/**
* SPDX-License-Identifier: Apache-2.0
*
* 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;
import { SignatureChecker } from "./util/SignatureChecker.sol";
import { MessageHashUtils } from "./util/MessageHashUtils.sol";
/**
* @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;
}/**
* SPDX-License-Identifier: Apache-2.0
*
* 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);
}// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.4;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/token/ERC20/extensions/draft-ERC20PermitUpgradeable.sol";
import "./WithBlockedList.sol";
/*
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 by the base token, 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 virtual onlyOwner {
_mint(_destination, _amount);
emit Mint(_destination, _amount);
}
function redeem(uint256 _amount) public virtual 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 Redeem(uint256 _amount);
event DestroyedBlockedFunds(address indexed _blockedUser, uint256 _balance);
}// SPDX-License-Identifier: Apache 2.0
import "./TetherToken.sol";
import "./EIP3009.sol";
import "./util/SignatureChecker.sol";
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:
*
* SPDX-License-Identifier: Apache-2.0
*
* 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:
*
* SPDX-License-Identifier: Apache-2.0
*
* 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:
*
* SPDX-License-Identifier: Apache-2.0
*
* 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:
*
* SPDX-License-Identifier: Apache-2.0
*
* 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:
*
* SPDX-License-Identifier: Apache-2.0
*
* 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:
*
* SPDX-License-Identifier: Apache-2.0
*
* 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;
}/**
* SPDX-License-Identifier: Apache-2.0
*
* 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);
}
}/**
* SPDX-License-Identifier: Apache-2.0
*
* 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)
}
}
}/**
* SPDX-License-Identifier: Apache-2.0
*
* 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;
import { ECRecover } from "./ECRecover.sol";
import { IERC1271 } from "../interfaces/IERC1271.sol";
/**
* @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;
}
}// SPDX-License-Identifier: Apache 2.0
pragma solidity 0.8.4;
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
/*
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);
}// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts/utils/introspection/IERC165.sol";
/// @title IERC7802
/// @notice Defines the interface for crosschain ERC20 transfers.
interface IERC7802 is IERC165 {
/// @notice Emitted when a crosschain transfer mints tokens.
/// @param to Address of the account tokens are being minted for.
/// @param amount Amount of tokens minted.
/// @param sender Address of the caller (msg.sender) who invoked crosschainMint.
event CrosschainMint(address indexed to, uint256 amount, address indexed sender);
/// @notice Emitted when a crosschain transfer burns tokens.
/// @param from Address of the account tokens are being burned from.
/// @param amount Amount of tokens burned.
/// @param sender Address of the caller (msg.sender) who invoked crosschainBurn.
event CrosschainBurn(address indexed from, uint256 amount, address indexed sender);
/// @notice Mint tokens through a crosschain transfer.
/// @param _to Address to mint tokens to.
/// @param _amount Amount of tokens to mint.
function crosschainMint(address _to, uint256 _amount) external;
/// @notice Burn tokens through a crosschain transfer.
/// @param _from Address to burn tokens from.
/// @param _amount Amount of tokens to burn.
function crosschainBurn(address _from, uint256 _amount) external;
}{
"optimizer": {
"enabled": true,
"runs": 100000
},
"outputSelection": {
"*": {
"*": [
"evm.bytecode",
"evm.deployedBytecode",
"devdoc",
"userdoc",
"metadata",
"abi"
]
}
},
"libraries": {}
}Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
Contract ABI
API[{"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":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"CrosschainBurn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"CrosschainMint","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":"oftContract","type":"address"}],"name":"LogSetOFTContract","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"name","type":"string"},{"indexed":false,"internalType":"string","name":"symbol","type":"string"}],"name":"LogUpdateNameAndSymbol","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":"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":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"crosschainBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_destination","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"crosschainMint","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":"oftContract","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[{"internalType":"address","name":"_oftContract","type":"address"}],"name":"setOFTContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","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"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"updateNameAndSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"}]Contract Creation Code
60806040523480156200001157600080fd5b50600054610100900460ff16806200002c575060005460ff16155b620000945760405162461bcd60e51b815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201526d191e481a5b9a5d1a585b1a5e995960921b606482015260840160405180910390fd5b600054610100900460ff16158015620000b7576000805461ffff19166101011790555b8015620000ca576000805461ff00191690555b506145c580620000db6000396000f3fe608060405234801561001057600080fd5b50600436106102e95760003560e01c80637f2eecc311610191578063cf092995116100e3578063e3ee160e11610097578063ef55bec611610071578063ef55bec6146106f5578063f2fde38b14610708578063fbac39511461071b57600080fd5b8063e3ee160e14610688578063e94a01021461069b578063eaf9d194146106e257600080fd5b8063d9169487116100c8578063d916948714610608578063db006a751461062f578063dd62ed3e1461064257600080fd5b8063cf092995146105e2578063d505accf146105f557600080fd5b806396d6487911610145578063a457c2d71161011f578063a457c2d7146105a9578063a9059cbb146105bc578063b7b72899146105cf57600080fd5b806396d648791461054b5780639fd5a6cf1461056f578063a0cc6a681461058257600080fd5b806388b7ab631161017657806388b7ab63146105125780638da5cb5b1461052557806395d89b411461054357600080fd5b80637f2eecc3146104d85780638040a2c7146104ff57600080fd5b806323b872dd1161024a5780633c7c9b90116101fe57806370a08231116101d857806370a0823114610487578063715018a6146104bd5780637ecebe00146104c557600080fd5b80633c7c9b901461044e57806340c10f19146104615780635a049a701461047457600080fd5b8063313ce5671161022f578063313ce5671461041d5780633644e51514610433578063395093511461043b57600080fd5b806323b872dd146103f75780632b8c49e31461040a57600080fd5b806318160ddd116102a15780631a14f449116102865780631a14f4491461038b5780631e89d5451461039e578063232849c3146103b157600080fd5b806318160ddd1461036657806318bf50771461037857600080fd5b8063095ea7b3116102d2578063095ea7b31461032b5780630e27a3851461033e5780631624f6c61461035357600080fd5b806301ffc9a7146102ee57806306fdde0314610316575b600080fd5b6103016102fc36600461426e565b61073e565b60405190151581526020015b60405180910390f35b61031e6107d7565b60405161030d9190614417565b610301610339366004614122565b61088c565b61035161034c366004613ec2565b6108a2565b005b61035161036136600461430f565b610a3b565b6035545b60405190815260200161030d565b610351610386366004614122565b610b9d565b610351610399366004613ec2565b610ccb565b6103516103ac3660046141ed565b610dc0565b610163546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030d565b610301610405366004613f0e565b610f0a565b610351610418366004614122565b610f99565b6101005460405160ff909116815260200161030d565b61036a6110bf565b610301610449366004614122565b6110c9565b61035161045c366004613ec2565b611112565b61035161046f366004614122565b61120a565b6103516104823660046141a0565b6112dd565b61036a610495366004613ec2565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610351611339565b61036a6104d3366004613ec2565b6113c6565b61036a7fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b61035161050d366004613ec2565b6113f1565b610351610520366004613fb9565b6114e2565b60cc5473ffffffffffffffffffffffffffffffffffffffff166103d2565b61031e61157f565b610301610559366004613ec2565b60ff602081905260009182526040909120541681565b61035161057d366004613f49565b6115ac565b61036a7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6103016105b7366004614122565b6115b9565b6103016105ca366004614122565b611691565b6103516105dd36600461414b565b61169e565b6103516105f0366004613fb9565b6116ae565b6103516106033660046140b9565b611737565b61036a7f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b61035161063d366004614380565b61179d565b61036a610650366004613edc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61035161069636600461403c565b61187c565b6103016106a9366004614122565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815261010160209081526040808320938352929052205460ff1690565b6103516106f03660046142ae565b611974565b61035161070336600461403c565b611a5c565b610351610716366004613ec2565b611b3e565b610301610729366004613ec2565b60fe6020526000908152604090205460ff1681565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f333319940000000000000000000000000000000000000000000000000000000014806107d157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b606061016480546107e7906144aa565b15905061087f5761016480546107fc906144aa565b80601f0160208091040260200160405190810160405280929190818152602001828054610828906144aa565b80156108755780601f1061084a57610100808354040283529160200191610875565b820191906000526020600020905b81548152906001019060200180831161085857829003601f168201915b5050505050905090565b610887611c6e565b905090565b6000610899338484611c7d565b50600192915050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610928576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260fe602052604090205460ff166109b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546574686572546f6b656e3a2075736572206973206e6f7420626c6f636b6564604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603360205260409020546109e78282611e30565b8173ffffffffffffffffffffffffffffffffffffffff167f6a2859ae7902313752498feb80a014e6e7275fe964c79aa965db815db1c7f1e982604051610a2f91815260200190565b60405180910390a25050565b600054610100900460ff1680610a54575060005460ff16155b610ae0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff16158015610b1f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61010080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8416179055610b55612029565b610b5f848461214e565b610b6884612277565b8015610b9757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b6101635473ffffffffffffffffffffffffffffffffffffffff163314610c1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f6e6c79204f46542063616e2063616c6c000000000000000000000000000000604482015260640161091f565b610c2982826123de565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610c7191815260200190565b60405180910390a2604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907fde22baff038e3a3e08407cbdf617deed74e869a7ba517df611e33131c6e6ea04906020015b60405180910390a35050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f665918c9e02eb2fd85acca3969cb054fc84c138e60ec4af22ab6ef2fd4c93c279190a250565b828114610e4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f546574686572546f6b656e3a206d756c74695472616e73666572206d69736d6160448201527f7463680000000000000000000000000000000000000000000000000000000000606482015260840161091f565b60005b83811015610f0357610ef0858583818110610e96577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610eab9190613ec2565b848484818110610ee4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135611691565b5080610efb816144f8565b915050610e52565b5050505050565b33600090815260fe602052604081205460ff1615610f84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b610f8f84848461250a565b90505b9392505050565b6101635473ffffffffffffffffffffffffffffffffffffffff16331461101b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f6e6c79204f46542063616e2063616c6c000000000000000000000000000000604482015260640161091f565b6110258282611e30565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161106d91815260200190565b60405180910390a2604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907fb90795a66650155983e242cac3e1ac1a4dc26f8ed2987f3ce416a34e00111fd490602001610cbf565b60006108876125f0565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161089991859061110d90869061444f565b611c7d565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f406bbf2d8d145125adf1198d2cf8a67c66cc4bb0ab01c37dccd4f7c0aae1e7c79190a250565b60cc5473ffffffffffffffffffffffffffffffffffffffff16331461128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b61129582826123de565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610a2f91815260200190565b60408051602081018490529081018290527fff0000000000000000000000000000000000000000000000000000000000000060f885901b166060820152610f03908690869060610160405160208183030381529060405261266a565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146113ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b6113c46000612770565b565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546107d1565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b61016380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f140c7f3c4dd16fa102e8e866bdbed4553b3cbe199ca01455115be3efc7ec6b6290600090a250565b33600090815260fe602052604090205460ff161561155c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61156b878787878787876127e7565b6115768787876128f8565b50505050505050565b6060610165805461158f906144aa565b1590506115a45761016580546107fc906144aa565b610887612bb6565b610f038585858585612bc5565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120548281101561167a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161091f565b6116873385858403611c7d565b5060019392505050565b60006108993384846128f8565b6116a983838361266a565b505050565b33600090815260fe602052604090205460ff1615611728576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61156b87878787878787612d44565b6115768787878786868960405160200161178993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612bc5565b60cc5473ffffffffffffffffffffffffffffffffffffffff16331461181e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b61184661184060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b82611e30565b6040518181527f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a449060200160405180910390a150565b33600090815260fe602052604090205460ff16156118f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61195e89898989898988888b60405160200161194a93929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612d44565b6119698989896128f8565b505050505050505050565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146119f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b8151611a0990610164906020850190613d00565b508051611a1e90610165906020840190613d00565b507f90322812e6761e312b99024e89e7408714261709c6d7f874d796927e813a6f728282604051611a5092919061442a565b60405180910390a15050565b33600090815260fe602052604090205460ff1615611ad6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61195e89898989898988888b604051602001611b2a93929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b6040516020818303038152906040526127e7565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116611c62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161091f565b611c6b81612770565b50565b6060603680546107fc906144aa565b73ffffffffffffffffffffffffffffffffffffffff8316611d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff8216611dc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ed3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161091f565b611edf82600083612dcc565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015611f95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603360205260408120838303905560358054849290611fd1908490614467565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600054610100900460ff1680612042575060005460ff16155b6120ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561210d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b612115612f24565b61211d613038565b8015611c6b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680612167575060005460ff16155b6121f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561223257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61223a612f24565b6122448383613125565b80156116a957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680612290575060005460ff16155b61231c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561235b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b612363612f24565b6123a2826040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613264565b6123ab82613398565b80156123da57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b73ffffffffffffffffffffffffffffffffffffffff821661245b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161091f565b61246760008383612dcc565b8060356000828254612479919061444f565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040812080548392906124b390849061444f565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60006125178484846128f8565b73ffffffffffffffffffffffffffffffffffffffff84166000908152603460209081526040808320338452909152902054828110156125d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000606482015260840161091f565b6125e58533858403611c7d565b506001949350505050565b60006108877f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61261e6134d2565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b61267483836134e8565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429602082015273ffffffffffffffffffffffffffffffffffffffff851691810191909152606081018390526126e99084906080015b6040516020818303038152906040528051906020012083613584565b73ffffffffffffffffffffffffffffffffffffffff831660008181526101016020908152604080832086845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b60cc805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b73ffffffffffffffffffffffffffffffffffffffff86163314612866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546574686572546f6b656e3a20746f20213d206d73672e73656e646572000000604482015260640161091f565b6128728783868661363a565b604080517fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526128ee908890610100016126cd565b6115768783613716565b73ffffffffffffffffffffffffffffffffffffffff831661299b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff8216612a3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161091f565b612a49838383612dcc565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612aff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260336020526040808220858503905591851681529081208054849290612b4390849061444f565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ba991815260200190565b60405180910390a3610b97565b6060603780546107fc906144aa565b81421115612c2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015260640161091f565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9868686612c5e8a61379c565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810184905260e0016040516020818303038152906040528051906020012090506000612cc6826137d1565b9050612cd387828561383a565b612d39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f454950323631323a20696e76616c6964207369676e6174757265000000000000604482015260640161091f565b611576878787611c7d565b612d508783868661363a565b604080517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526128ee908890610100016126cd565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260fe602052604090205460ff161580612e18575060cc5473ffffffffffffffffffffffffffffffffffffffff1633145b612e7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546574686572546f6b656e3a2066726f6d20697320626c6f636b656400000000604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff82163014156116a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f546574686572546f6b656e3a207472616e7366657220746f2074686520636f6e60448201527f7472616374206164647265737300000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1680612f3d575060005460ff16155b612fc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561211d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790558015611c6b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680613051575060005460ff16155b6130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561311c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61211d33612770565b600054610100900460ff168061313e575060005460ff16155b6131ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561320957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b825161321c906036906020860190613d00565b508151613230906037906020850190613d00565b5080156116a957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff168061327d575060005460ff16155b613309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561334857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b825160208085019190912083519184019190912060659190915560665580156116a957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff16806133b1575060005460ff16155b61343d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561347c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a5580156123da57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b60006134dc6107d7565b80519060200120905090565b73ffffffffffffffffffffffffffffffffffffffff821660009081526101016020908152604080832084845290915290205460ff16156123da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a206175746820696e76616c696400000000000000604482015260640161091f565b6135d4836135ce6135936110bf565b856040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b8361383a565b6116a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546574686572546f6b656e3a20696e76616c6964207369676e61747572650000604482015260640161091f565b8142116136a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546574686572546f6b656e3a2061757468206561726c79000000000000000000604482015260640161091f565b80421061370c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a2061757468206578706972656400000000000000604482015260640161091f565b610b9784846134e8565b73ffffffffffffffffffffffffffffffffffffffff821660008181526101016020908152604080832085845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006107d16137de6125f0565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000833b613881578373ffffffffffffffffffffffffffffffffffffffff16613863848461388c565b73ffffffffffffffffffffffffffffffffffffffff16149050610f92565b610f8f848484613947565b6000815160411461391f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45435265636f7665723a20696e76616c6964207369676e6174757265206c656e60448201527f6774680000000000000000000000000000000000000000000000000000000000606482015260840161091f565b60208201516040830151606084015160001a61393d86828585613aa4565b9695505050505050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b868660405160240161397e9291906143fe565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051613a0791906143e2565b600060405180830381855afa9150503d8060008114613a42576040519150601f19603f3d011682016040523d82523d6000602084013e613a47565b606091505b5091509150818015613a5b57506020815110155b801561393d575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090613a999083016020908101908401614256565b149695505050505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613b56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027732760448201527f2076616c75650000000000000000000000000000000000000000000000000000606482015260840161091f565b8360ff16601b14158015613b6e57508360ff16601c14155b15613bfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027762760448201527f2076616c75650000000000000000000000000000000000000000000000000000606482015260840161091f565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613c4f573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116613cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45435265636f7665723a20696e76616c6964207369676e617475726500000000604482015260640161091f565b95945050505050565b828054613d0c906144aa565b90600052602060002090601f016020900481019282613d2e5760008555613d74565b82601f10613d4757805160ff1916838001178555613d74565b82800160010185558215613d74579182015b82811115613d74578251825591602001919060010190613d59565b50613d80929150613d84565b5090565b5b80821115613d805760008155600101613d85565b803573ffffffffffffffffffffffffffffffffffffffff81168114613dbd57600080fd5b919050565b60008083601f840112613dd3578081fd5b50813567ffffffffffffffff811115613dea578182fd5b6020830191508360208260051b8501011115613e0557600080fd5b9250929050565b600082601f830112613e1c578081fd5b813567ffffffffffffffff80821115613e3757613e37614560565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613e7d57613e7d614560565b81604052838152866020858801011115613e95578485fd5b8360208701602083013792830160200193909352509392505050565b803560ff81168114613dbd57600080fd5b600060208284031215613ed3578081fd5b610f9282613d99565b60008060408385031215613eee578081fd5b613ef783613d99565b9150613f0560208401613d99565b90509250929050565b600080600060608486031215613f22578081fd5b613f2b84613d99565b9250613f3960208501613d99565b9150604084013590509250925092565b600080600080600060a08688031215613f60578081fd5b613f6986613d99565b9450613f7760208701613d99565b93506040860135925060608601359150608086013567ffffffffffffffff811115613fa0578182fd5b613fac88828901613e0c565b9150509295509295909350565b600080600080600080600060e0888a031215613fd3578182fd5b613fdc88613d99565b9650613fea60208901613d99565b955060408801359450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff811115614021578182fd5b61402d8a828b01613e0c565b91505092959891949750929550565b60008060008060008060008060006101208a8c03121561405a578182fd5b6140638a613d99565b985061407160208b01613d99565b975060408a0135965060608a0135955060808a0135945060a08a0135935061409b60c08b01613eb1565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a0312156140d3578081fd5b6140dc88613d99565b96506140ea60208901613d99565b9550604088013594506060880135935061410660808901613eb1565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215614134578182fd5b61413d83613d99565b946020939093013593505050565b60008060006060848603121561415f578081fd5b61416884613d99565b925060208401359150604084013567ffffffffffffffff81111561418a578182fd5b61419686828701613e0c565b9150509250925092565b600080600080600060a086880312156141b7578283fd5b6141c086613d99565b9450602086013593506141d560408701613eb1565b94979396509394606081013594506080013592915050565b60008060008060408587031215614202578182fd5b843567ffffffffffffffff80821115614219578384fd5b61422588838901613dc2565b9096509450602087013591508082111561423d578384fd5b5061424a87828801613dc2565b95989497509550505050565b600060208284031215614267578081fd5b5051919050565b60006020828403121561427f578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f92578182fd5b600080604083850312156142c0578182fd5b823567ffffffffffffffff808211156142d7578384fd5b6142e386838701613e0c565b935060208501359150808211156142f8578283fd5b5061430585828601613e0c565b9150509250929050565b600080600060608486031215614323578081fd5b833567ffffffffffffffff8082111561433a578283fd5b61434687838801613e0c565b9450602086013591508082111561435b578283fd5b5061436886828701613e0c565b92505061437760408501613eb1565b90509250925092565b600060208284031215614391578081fd5b5035919050565b600081518084526143b081602086016020860161447e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516143f481846020870161447e565b9190910192915050565b828152604060208201526000610f8f6040830184614398565b602081526000610f926020830184614398565b60408152600061443d6040830185614398565b8281036020840152613cf78185614398565b6000821982111561446257614462614531565b500190565b60008282101561447957614479614531565b500390565b60005b83811015614499578181015183820152602001614481565b83811115610b975750506000910152565b600181811c908216806144be57607f821691505b602082108114156137cb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561452a5761452a614531565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea2646970667358221220b63ccc36ce0285e12c6580ef5c2f12a86f8c0ab88a1ed9d34ef996133e48427a64736f6c63430008040033
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106102e95760003560e01c80637f2eecc311610191578063cf092995116100e3578063e3ee160e11610097578063ef55bec611610071578063ef55bec6146106f5578063f2fde38b14610708578063fbac39511461071b57600080fd5b8063e3ee160e14610688578063e94a01021461069b578063eaf9d194146106e257600080fd5b8063d9169487116100c8578063d916948714610608578063db006a751461062f578063dd62ed3e1461064257600080fd5b8063cf092995146105e2578063d505accf146105f557600080fd5b806396d6487911610145578063a457c2d71161011f578063a457c2d7146105a9578063a9059cbb146105bc578063b7b72899146105cf57600080fd5b806396d648791461054b5780639fd5a6cf1461056f578063a0cc6a681461058257600080fd5b806388b7ab631161017657806388b7ab63146105125780638da5cb5b1461052557806395d89b411461054357600080fd5b80637f2eecc3146104d85780638040a2c7146104ff57600080fd5b806323b872dd1161024a5780633c7c9b90116101fe57806370a08231116101d857806370a0823114610487578063715018a6146104bd5780637ecebe00146104c557600080fd5b80633c7c9b901461044e57806340c10f19146104615780635a049a701461047457600080fd5b8063313ce5671161022f578063313ce5671461041d5780633644e51514610433578063395093511461043b57600080fd5b806323b872dd146103f75780632b8c49e31461040a57600080fd5b806318160ddd116102a15780631a14f449116102865780631a14f4491461038b5780631e89d5451461039e578063232849c3146103b157600080fd5b806318160ddd1461036657806318bf50771461037857600080fd5b8063095ea7b3116102d2578063095ea7b31461032b5780630e27a3851461033e5780631624f6c61461035357600080fd5b806301ffc9a7146102ee57806306fdde0314610316575b600080fd5b6103016102fc36600461426e565b61073e565b60405190151581526020015b60405180910390f35b61031e6107d7565b60405161030d9190614417565b610301610339366004614122565b61088c565b61035161034c366004613ec2565b6108a2565b005b61035161036136600461430f565b610a3b565b6035545b60405190815260200161030d565b610351610386366004614122565b610b9d565b610351610399366004613ec2565b610ccb565b6103516103ac3660046141ed565b610dc0565b610163546103d29073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200161030d565b610301610405366004613f0e565b610f0a565b610351610418366004614122565b610f99565b6101005460405160ff909116815260200161030d565b61036a6110bf565b610301610449366004614122565b6110c9565b61035161045c366004613ec2565b611112565b61035161046f366004614122565b61120a565b6103516104823660046141a0565b6112dd565b61036a610495366004613ec2565b73ffffffffffffffffffffffffffffffffffffffff1660009081526033602052604090205490565b610351611339565b61036a6104d3366004613ec2565b6113c6565b61036a7fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de881565b61035161050d366004613ec2565b6113f1565b610351610520366004613fb9565b6114e2565b60cc5473ffffffffffffffffffffffffffffffffffffffff166103d2565b61031e61157f565b610301610559366004613ec2565b60ff602081905260009182526040909120541681565b61035161057d366004613f49565b6115ac565b61036a7f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a226781565b6103016105b7366004614122565b6115b9565b6103016105ca366004614122565b611691565b6103516105dd36600461414b565b61169e565b6103516105f0366004613fb9565b6116ae565b6103516106033660046140b9565b611737565b61036a7f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a159742981565b61035161063d366004614380565b61179d565b61036a610650366004613edc565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260346020908152604080832093909416825291909152205490565b61035161069636600461403c565b61187c565b6103016106a9366004614122565b73ffffffffffffffffffffffffffffffffffffffff91909116600090815261010160209081526040808320938352929052205460ff1690565b6103516106f03660046142ae565b611974565b61035161070336600461403c565b611a5c565b610351610716366004613ec2565b611b3e565b610301610729366004613ec2565b60fe6020526000908152604090205460ff1681565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f333319940000000000000000000000000000000000000000000000000000000014806107d157507fffffffff0000000000000000000000000000000000000000000000000000000082167f01ffc9a700000000000000000000000000000000000000000000000000000000145b92915050565b606061016480546107e7906144aa565b15905061087f5761016480546107fc906144aa565b80601f0160208091040260200160405190810160405280929190818152602001828054610828906144aa565b80156108755780601f1061084a57610100808354040283529160200191610875565b820191906000526020600020905b81548152906001019060200180831161085857829003601f168201915b5050505050905090565b610887611c6e565b905090565b6000610899338484611c7d565b50600192915050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610928576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064015b60405180910390fd5b73ffffffffffffffffffffffffffffffffffffffff8116600090815260fe602052604090205460ff166109b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546574686572546f6b656e3a2075736572206973206e6f7420626c6f636b6564604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff81166000908152603360205260409020546109e78282611e30565b8173ffffffffffffffffffffffffffffffffffffffff167f6a2859ae7902313752498feb80a014e6e7275fe964c79aa965db815db1c7f1e982604051610a2f91815260200190565b60405180910390a25050565b600054610100900460ff1680610a54575060005460ff16155b610ae0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff16158015610b1f57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61010080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660ff8416179055610b55612029565b610b5f848461214e565b610b6884612277565b8015610b9757600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b50505050565b6101635473ffffffffffffffffffffffffffffffffffffffff163314610c1f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f6e6c79204f46542063616e2063616c6c000000000000000000000000000000604482015260640161091f565b610c2982826123de565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610c7191815260200190565b60405180910390a2604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907fde22baff038e3a3e08407cbdf617deed74e869a7ba517df611e33131c6e6ea04906020015b60405180910390a35050565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314610d4c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00169055517f665918c9e02eb2fd85acca3969cb054fc84c138e60ec4af22ab6ef2fd4c93c279190a250565b828114610e4f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f546574686572546f6b656e3a206d756c74695472616e73666572206d69736d6160448201527f7463680000000000000000000000000000000000000000000000000000000000606482015260840161091f565b60005b83811015610f0357610ef0858583818110610e96577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9050602002016020810190610eab9190613ec2565b848484818110610ee4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90506020020135611691565b5080610efb816144f8565b915050610e52565b5050505050565b33600090815260fe602052604081205460ff1615610f84576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b610f8f84848461250a565b90505b9392505050565b6101635473ffffffffffffffffffffffffffffffffffffffff16331461101b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601160248201527f4f6e6c79204f46542063616e2063616c6c000000000000000000000000000000604482015260640161091f565b6110258282611e30565b8173ffffffffffffffffffffffffffffffffffffffff167fcc16f5dbb4873280815c1ee09dbd06736cffcc184412cf7a71a0fdb75d397ca58260405161106d91815260200190565b60405180910390a2604051818152339073ffffffffffffffffffffffffffffffffffffffff8416907fb90795a66650155983e242cac3e1ac1a4dc26f8ed2987f3ce416a34e00111fd490602001610cbf565b60006108876125f0565b33600081815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168452909152812054909161089991859061110d90869061444f565b611c7d565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116600081815260fe602052604080822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055517f406bbf2d8d145125adf1198d2cf8a67c66cc4bb0ab01c37dccd4f7c0aae1e7c79190a250565b60cc5473ffffffffffffffffffffffffffffffffffffffff16331461128b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b61129582826123de565b8173ffffffffffffffffffffffffffffffffffffffff167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610a2f91815260200190565b60408051602081018490529081018290527fff0000000000000000000000000000000000000000000000000000000000000060f885901b166060820152610f03908690869060610160405160208183030381529060405261266a565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146113ba576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b6113c46000612770565b565b73ffffffffffffffffffffffffffffffffffffffff81166000908152609960205260408120546107d1565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611472576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b61016380547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff83169081179091556040517f140c7f3c4dd16fa102e8e866bdbed4553b3cbe199ca01455115be3efc7ec6b6290600090a250565b33600090815260fe602052604090205460ff161561155c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61156b878787878787876127e7565b6115768787876128f8565b50505050505050565b6060610165805461158f906144aa565b1590506115a45761016580546107fc906144aa565b610887612bb6565b610f038585858585612bc5565b33600090815260346020908152604080832073ffffffffffffffffffffffffffffffffffffffff861684529091528120548281101561167a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f000000000000000000000000000000000000000000000000000000606482015260840161091f565b6116873385858403611c7d565b5060019392505050565b60006108993384846128f8565b6116a983838361266a565b505050565b33600090815260fe602052604090205460ff1615611728576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61156b87878787878787612d44565b6115768787878786868960405160200161178993929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612bc5565b60cc5473ffffffffffffffffffffffffffffffffffffffff16331461181e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b61184661184060cc5473ffffffffffffffffffffffffffffffffffffffff1690565b82611e30565b6040518181527f702d5967f45f6513a38ffc42d6ba9bf230bd40e8f53b16363c7eb4fd2deb9a449060200160405180910390a150565b33600090815260fe602052604090205460ff16156118f6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61195e89898989898988888b60405160200161194a93929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b604051602081830303815290604052612d44565b6119698989896128f8565b505050505050505050565b60cc5473ffffffffffffffffffffffffffffffffffffffff1633146119f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b8151611a0990610164906020850190613d00565b508051611a1e90610165906020840190613d00565b507f90322812e6761e312b99024e89e7408714261709c6d7f874d796927e813a6f728282604051611a5092919061442a565b60405180910390a15050565b33600090815260fe602052604090205460ff1615611ad6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f426c6f636b65643a206d73672e73656e64657220697320626c6f636b65640000604482015260640161091f565b61195e89898989898988888b604051602001611b2a93929190928352602083019190915260f81b7fff0000000000000000000000000000000000000000000000000000000000000016604082015260410190565b6040516020818303038152906040526127e7565b60cc5473ffffffffffffffffffffffffffffffffffffffff163314611bbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff8116611c62576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161091f565b611c6b81612770565b50565b6060603680546107fc906144aa565b73ffffffffffffffffffffffffffffffffffffffff8316611d1f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f7265737300000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff8216611dc2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f7373000000000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526034602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b73ffffffffffffffffffffffffffffffffffffffff8216611ed3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f7300000000000000000000000000000000000000000000000000000000000000606482015260840161091f565b611edf82600083612dcc565b73ffffffffffffffffffffffffffffffffffffffff821660009081526033602052604090205481811015611f95576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f6365000000000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff83166000908152603360205260408120838303905560358054849290611fd1908490614467565b909155505060405182815260009073ffffffffffffffffffffffffffffffffffffffff8516907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a3505050565b600054610100900460ff1680612042575060005460ff16155b6120ce576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561210d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b612115612f24565b61211d613038565b8015611c6b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680612167575060005460ff16155b6121f3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561223257600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61223a612f24565b6122448383613125565b80156116a957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff1680612290575060005460ff16155b61231c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561235b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b612363612f24565b6123a2826040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250613264565b6123ab82613398565b80156123da57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555b5050565b73ffffffffffffffffffffffffffffffffffffffff821661245b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640161091f565b61246760008383612dcc565b8060356000828254612479919061444f565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260336020526040812080548392906124b390849061444f565b909155505060405181815273ffffffffffffffffffffffffffffffffffffffff8316906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef9060200160405180910390a35050565b60006125178484846128f8565b73ffffffffffffffffffffffffffffffffffffffff84166000908152603460209081526040808320338452909152902054828110156125d8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602860248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206160448201527f6c6c6f77616e6365000000000000000000000000000000000000000000000000606482015260840161091f565b6125e58533858403611c7d565b506001949350505050565b60006108877f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f61261e6134d2565b6066546040805160208101859052908101839052606081018290524660808201523060a082015260009060c0016040516020818303038152906040528051906020012090509392505050565b61267483836134e8565b604080517f158b0a9edf7a828aad02f63cd515c68ef2f50ba807396f6d12842833a1597429602082015273ffffffffffffffffffffffffffffffffffffffff851691810191909152606081018390526126e99084906080015b6040516020818303038152906040528051906020012083613584565b73ffffffffffffffffffffffffffffffffffffffff831660008181526101016020908152604080832086845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518492917f1cdd46ff242716cdaa72d159d339a485b3438398348d68f09d7c8c0a59353d8191a3505050565b60cc805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b73ffffffffffffffffffffffffffffffffffffffff86163314612866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546574686572546f6b656e3a20746f20213d206d73672e73656e646572000000604482015260640161091f565b6128728783868661363a565b604080517fd099cc98ef71107a616c4f0f941f04c322d8e254fe26b3c6668db87aae413de8602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526128ee908890610100016126cd565b6115768783613716565b73ffffffffffffffffffffffffffffffffffffffff831661299b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f6472657373000000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff8216612a3e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161091f565b612a49838383612dcc565b73ffffffffffffffffffffffffffffffffffffffff831660009081526033602052604090205481811015612aff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e63650000000000000000000000000000000000000000000000000000606482015260840161091f565b73ffffffffffffffffffffffffffffffffffffffff808516600090815260336020526040808220858503905591851681529081208054849290612b4390849061444f565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051612ba991815260200190565b60405180910390a3610b97565b6060603780546107fc906144aa565b81421115612c2f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f45524332305065726d69743a206578706972656420646561646c696e65000000604482015260640161091f565b60007f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9868686612c5e8a61379c565b60408051602081019690965273ffffffffffffffffffffffffffffffffffffffff94851690860152929091166060840152608083015260a082015260c0810184905260e0016040516020818303038152906040528051906020012090506000612cc6826137d1565b9050612cd387828561383a565b612d39576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601a60248201527f454950323631323a20696e76616c6964207369676e6174757265000000000000604482015260640161091f565b611576878787611c7d565b612d508783868661363a565b604080517f7c7c6cdb67a18743f49ec6fa9b35f50d52ed05cbed4cc592e13b44501c1a2267602082015273ffffffffffffffffffffffffffffffffffffffff808a169282019290925290871660608201526080810186905260a0810185905260c0810184905260e081018390526128ee908890610100016126cd565b73ffffffffffffffffffffffffffffffffffffffff8316600090815260fe602052604090205460ff161580612e18575060cc5473ffffffffffffffffffffffffffffffffffffffff1633145b612e7e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546574686572546f6b656e3a2066726f6d20697320626c6f636b656400000000604482015260640161091f565b73ffffffffffffffffffffffffffffffffffffffff82163014156116a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602d60248201527f546574686572546f6b656e3a207472616e7366657220746f2074686520636f6e60448201527f7472616374206164647265737300000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1680612f3d575060005460ff16155b612fc9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561211d57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790558015611c6b57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16905550565b600054610100900460ff1680613051575060005460ff16155b6130dd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561311c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b61211d33612770565b600054610100900460ff168061313e575060005460ff16155b6131ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561320957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b825161321c906036906020860190613d00565b508151613230906037906020850190613d00565b5080156116a957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff168061327d575060005460ff16155b613309576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561334857600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b825160208085019190912083519184019190912060659190915560665580156116a957600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff169055505050565b600054610100900460ff16806133b1575060005460ff16155b61343d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602e60248201527f496e697469616c697a61626c653a20636f6e747261637420697320616c72656160448201527f647920696e697469616c697a6564000000000000000000000000000000000000606482015260840161091f565b600054610100900460ff1615801561347c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0000166101011790555b7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9609a5580156123da57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff1690555050565b60006134dc6107d7565b80519060200120905090565b73ffffffffffffffffffffffffffffffffffffffff821660009081526101016020908152604080832084845290915290205460ff16156123da576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a206175746820696e76616c696400000000000000604482015260640161091f565b6135d4836135ce6135936110bf565b856040517f19010000000000000000000000000000000000000000000000000000000000008152600281019290925260228201526042902090565b8361383a565b6116a9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546574686572546f6b656e3a20696e76616c6964207369676e61747572650000604482015260640161091f565b8142116136a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546574686572546f6b656e3a2061757468206561726c79000000000000000000604482015260640161091f565b80421061370c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f546574686572546f6b656e3a2061757468206578706972656400000000000000604482015260640161091f565b610b9784846134e8565b73ffffffffffffffffffffffffffffffffffffffff821660008181526101016020908152604080832085845290915280822080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055518392917f98de503528ee59b575ef0c0a2576a82497bfc029a5685b209e9ec333479b10a591a35050565b73ffffffffffffffffffffffffffffffffffffffff811660009081526099602052604090208054600181018255905b50919050565b60006107d16137de6125f0565b836040517f19010000000000000000000000000000000000000000000000000000000000006020820152602281018390526042810182905260009060620160405160208183030381529060405280519060200120905092915050565b6000833b613881578373ffffffffffffffffffffffffffffffffffffffff16613863848461388c565b73ffffffffffffffffffffffffffffffffffffffff16149050610f92565b610f8f848484613947565b6000815160411461391f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602360248201527f45435265636f7665723a20696e76616c6964207369676e6174757265206c656e60448201527f6774680000000000000000000000000000000000000000000000000000000000606482015260840161091f565b60208201516040830151606084015160001a61393d86828585613aa4565b9695505050505050565b60008060008573ffffffffffffffffffffffffffffffffffffffff16631626ba7e60e01b868660405160240161397e9291906143fe565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529181526020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff00000000000000000000000000000000000000000000000000000000909416939093179092529051613a0791906143e2565b600060405180830381855afa9150503d8060008114613a42576040519150601f19603f3d011682016040523d82523d6000602084013e613a47565b606091505b5091509150818015613a5b57506020815110155b801561393d575080517f1626ba7e0000000000000000000000000000000000000000000000000000000090613a999083016020908101908401614256565b149695505050505050565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613b56576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027732760448201527f2076616c75650000000000000000000000000000000000000000000000000000606482015260840161091f565b8360ff16601b14158015613b6e57508360ff16601c14155b15613bfb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f45435265636f7665723a20696e76616c6964207369676e61747572652027762760448201527f2076616c75650000000000000000000000000000000000000000000000000000606482015260840161091f565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613c4f573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116613cf7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f45435265636f7665723a20696e76616c6964207369676e617475726500000000604482015260640161091f565b95945050505050565b828054613d0c906144aa565b90600052602060002090601f016020900481019282613d2e5760008555613d74565b82601f10613d4757805160ff1916838001178555613d74565b82800160010185558215613d74579182015b82811115613d74578251825591602001919060010190613d59565b50613d80929150613d84565b5090565b5b80821115613d805760008155600101613d85565b803573ffffffffffffffffffffffffffffffffffffffff81168114613dbd57600080fd5b919050565b60008083601f840112613dd3578081fd5b50813567ffffffffffffffff811115613dea578182fd5b6020830191508360208260051b8501011115613e0557600080fd5b9250929050565b600082601f830112613e1c578081fd5b813567ffffffffffffffff80821115613e3757613e37614560565b604051601f83017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f01168101908282118183101715613e7d57613e7d614560565b81604052838152866020858801011115613e95578485fd5b8360208701602083013792830160200193909352509392505050565b803560ff81168114613dbd57600080fd5b600060208284031215613ed3578081fd5b610f9282613d99565b60008060408385031215613eee578081fd5b613ef783613d99565b9150613f0560208401613d99565b90509250929050565b600080600060608486031215613f22578081fd5b613f2b84613d99565b9250613f3960208501613d99565b9150604084013590509250925092565b600080600080600060a08688031215613f60578081fd5b613f6986613d99565b9450613f7760208701613d99565b93506040860135925060608601359150608086013567ffffffffffffffff811115613fa0578182fd5b613fac88828901613e0c565b9150509295509295909350565b600080600080600080600060e0888a031215613fd3578182fd5b613fdc88613d99565b9650613fea60208901613d99565b955060408801359450606088013593506080880135925060a0880135915060c088013567ffffffffffffffff811115614021578182fd5b61402d8a828b01613e0c565b91505092959891949750929550565b60008060008060008060008060006101208a8c03121561405a578182fd5b6140638a613d99565b985061407160208b01613d99565b975060408a0135965060608a0135955060808a0135945060a08a0135935061409b60c08b01613eb1565b925060e08a013591506101008a013590509295985092959850929598565b600080600080600080600060e0888a0312156140d3578081fd5b6140dc88613d99565b96506140ea60208901613d99565b9550604088013594506060880135935061410660808901613eb1565b925060a0880135915060c0880135905092959891949750929550565b60008060408385031215614134578182fd5b61413d83613d99565b946020939093013593505050565b60008060006060848603121561415f578081fd5b61416884613d99565b925060208401359150604084013567ffffffffffffffff81111561418a578182fd5b61419686828701613e0c565b9150509250925092565b600080600080600060a086880312156141b7578283fd5b6141c086613d99565b9450602086013593506141d560408701613eb1565b94979396509394606081013594506080013592915050565b60008060008060408587031215614202578182fd5b843567ffffffffffffffff80821115614219578384fd5b61422588838901613dc2565b9096509450602087013591508082111561423d578384fd5b5061424a87828801613dc2565b95989497509550505050565b600060208284031215614267578081fd5b5051919050565b60006020828403121561427f578081fd5b81357fffffffff0000000000000000000000000000000000000000000000000000000081168114610f92578182fd5b600080604083850312156142c0578182fd5b823567ffffffffffffffff808211156142d7578384fd5b6142e386838701613e0c565b935060208501359150808211156142f8578283fd5b5061430585828601613e0c565b9150509250929050565b600080600060608486031215614323578081fd5b833567ffffffffffffffff8082111561433a578283fd5b61434687838801613e0c565b9450602086013591508082111561435b578283fd5b5061436886828701613e0c565b92505061437760408501613eb1565b90509250925092565b600060208284031215614391578081fd5b5035919050565b600081518084526143b081602086016020860161447e565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600082516143f481846020870161447e565b9190910192915050565b828152604060208201526000610f8f6040830184614398565b602081526000610f926020830184614398565b60408152600061443d6040830185614398565b8281036020840152613cf78185614398565b6000821982111561446257614462614531565b500190565b60008282101561447957614479614531565b500390565b60005b83811015614499578181015183820152602001614481565b83811115610b975750506000910152565b600181811c908216806144be57607f821691505b602082108114156137cb577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561452a5761452a614531565b5060010190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fdfea2646970667358221220b63ccc36ce0285e12c6580ef5c2f12a86f8c0ab88a1ed9d34ef996133e48427a64736f6c63430008040033
Loading...
Loading
Loading...
Loading
Loading...
Loading
Net Worth in USD
$0.00
Net Worth in ETH
0
Multichain Portfolio | 35 Chains
| Chain | Token | Portfolio % | Price | Amount | Value |
|---|
Loading...
Loading
Loading...
Loading
Loading...
Loading
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.