Token migration announcement. Shiba San token contract has migrated to a new address.
ERC-20
Overview
Max Total Supply
10,000,000,000 SHIBA
Holders
22 (0.00%)
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 18 Decimals)
Balance
100,000,000 SHIBAValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
ShibaSanToken
Compiler Version
v0.8.26+commit.8a97fa7a
Contract Source Code (Solidity)
/** *Submitted for verification at Etherscan.io on 2024-08-10 */ // File: @openzeppelin/contracts/token/ERC20/IERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); /** * @dev Returns the value of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the value of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves a `value` amount of tokens from the caller's account to `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, uint256 value) 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 a `value` amount of tokens 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 value) external returns (bool); /** * @dev Moves a `value` amount of tokens from `from` to `to` using the * allowance mechanism. `value` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom(address from, address to, uint256 value) external returns (bool); } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; /** * @dev Interface for the optional metadata functions from the ERC20 standard. */ interface IERC20Metadata is IERC20 { /** * @dev Returns the name of the token. */ function name() external view returns (string memory); /** * @dev Returns the symbol of the token. */ function symbol() external view returns (string memory); /** * @dev Returns the decimals places of the token. */ function decimals() external view returns (uint8); } // File: @openzeppelin/contracts/utils/Context.sol // OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol) pragma solidity ^0.8.20; /** * @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 Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } function _contextSuffixLength() internal view virtual returns (uint256) { return 0; } } // File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol // OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol) pragma solidity ^0.8.20; /** * @dev Standard ERC20 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens. */ interface IERC20Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC20InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC20InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers. * @param spender Address that may be allowed to operate on tokens without being their owner. * @param allowance Amount of tokens a `spender` is allowed to operate with. * @param needed Minimum amount required to perform a transfer. */ error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC20InvalidApprover(address approver); /** * @dev Indicates a failure with the `spender` to be approved. Used in approvals. * @param spender Address that may be allowed to operate on tokens without being their owner. */ error ERC20InvalidSpender(address spender); } /** * @dev Standard ERC721 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens. */ interface IERC721Errors { /** * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20. * Used in balance queries. * @param owner Address of the current owner of a token. */ error ERC721InvalidOwner(address owner); /** * @dev Indicates a `tokenId` whose `owner` is the zero address. * @param tokenId Identifier number of a token. */ error ERC721NonexistentToken(uint256 tokenId); /** * @dev Indicates an error related to the ownership over a particular token. Used in transfers. * @param sender Address whose tokens are being transferred. * @param tokenId Identifier number of a token. * @param owner Address of the current owner of a token. */ error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC721InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC721InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param tokenId Identifier number of a token. */ error ERC721InsufficientApproval(address operator, uint256 tokenId); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC721InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC721InvalidOperator(address operator); } /** * @dev Standard ERC1155 Errors * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens. */ interface IERC1155Errors { /** * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. * @param balance Current balance for the interacting account. * @param needed Minimum amount required to perform a transfer. * @param tokenId Identifier number of a token. */ error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId); /** * @dev Indicates a failure with the token `sender`. Used in transfers. * @param sender Address whose tokens are being transferred. */ error ERC1155InvalidSender(address sender); /** * @dev Indicates a failure with the token `receiver`. Used in transfers. * @param receiver Address to which tokens are being transferred. */ error ERC1155InvalidReceiver(address receiver); /** * @dev Indicates a failure with the `operator`’s approval. Used in transfers. * @param operator Address that may be allowed to operate on tokens without being their owner. * @param owner Address of the current owner of a token. */ error ERC1155MissingApprovalForAll(address operator, address owner); /** * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals. * @param approver Address initiating an approval operation. */ error ERC1155InvalidApprover(address approver); /** * @dev Indicates a failure with the `operator` to be approved. Used in approvals. * @param operator Address that may be allowed to operate on tokens without being their owner. */ error ERC1155InvalidOperator(address operator); /** * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation. * Used in batch transfers. * @param idsLength Length of the array of token identifiers * @param valuesLength Length of the array of token amounts */ error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength); } // File: @openzeppelin/contracts/token/ERC20/ERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; /** * @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}. * * TIP: For a detailed writeup see our guide * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How * to implement supply mechanisms]. * * The default value of {decimals} is 18. To change this, you should override * this function so it returns a different value. * * We have followed general OpenZeppelin Contracts guidelines: functions revert * instead returning `false` on failure. This behavior is nonetheless * conventional and does not conflict with the expectations of ERC20 * applications. * * Additionally, an {Approval} event is emitted on calls to {transferFrom}. * This allows applications to reconstruct the allowance for all accounts just * by listening to said events. Other implementations of the EIP may not emit * these events, as it isn't required by the specification. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors { mapping(address account => uint256) private _balances; mapping(address account => mapping(address spender => uint256)) private _allowances; uint256 private _totalSupply; string private _name; string private _symbol; /** * @dev Sets the values for {name} and {symbol}. * * All two of these values are immutable: they can only be set once during * construction. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev Returns the name of the token. */ function name() public view virtual returns (string memory) { return _name; } /** * @dev Returns the symbol of the token, usually a shorter version of the * name. */ function symbol() public view virtual 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 default value returned by this function, unless * it's 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 returns (uint8) { return 18; } /** * @dev See {IERC20-totalSupply}. */ function totalSupply() public view virtual returns (uint256) { return _totalSupply; } /** * @dev See {IERC20-balanceOf}. */ function balanceOf(address account) public view virtual returns (uint256) { return _balances[account]; } /** * @dev See {IERC20-transfer}. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function transfer(address to, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _transfer(owner, to, value); return true; } /** * @dev See {IERC20-allowance}. */ function allowance(address owner, address spender) public view virtual returns (uint256) { return _allowances[owner][spender]; } /** * @dev See {IERC20-approve}. * * NOTE: If `value` is the maximum `uint256`, the allowance is not updated on * `transferFrom`. This is semantically equivalent to an infinite approval. * * Requirements: * * - `spender` cannot be the zero address. */ function approve(address spender, uint256 value) public virtual returns (bool) { address owner = _msgSender(); _approve(owner, spender, value); 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}. * * NOTE: Does not update the allowance if the current allowance * is the maximum `uint256`. * * Requirements: * * - `from` and `to` cannot be the zero address. * - `from` must have a balance of at least `value`. * - the caller must have allowance for ``from``'s tokens of at least * `value`. */ function transferFrom(address from, address to, uint256 value) public virtual returns (bool) { address spender = _msgSender(); _spendAllowance(from, spender, value); _transfer(from, to, value); return true; } /** * @dev Moves a `value` amount of tokens from `from` to `to`. * * 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. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _transfer(address from, address to, uint256 value) internal { if (from == address(0)) { revert ERC20InvalidSender(address(0)); } if (to == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(from, to, value); } /** * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from` * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding * this function. * * Emits a {Transfer} event. */ function _update(address from, address to, uint256 value) internal virtual { if (from == address(0)) { // Overflow check required: The rest of the code assumes that totalSupply never overflows _totalSupply += value; } else { uint256 fromBalance = _balances[from]; if (fromBalance < value) { revert ERC20InsufficientBalance(from, fromBalance, value); } unchecked { // Overflow not possible: value <= fromBalance <= totalSupply. _balances[from] = fromBalance - value; } } if (to == address(0)) { unchecked { // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply. _totalSupply -= value; } } else { unchecked { // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256. _balances[to] += value; } } emit Transfer(from, to, value); } /** * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0). * Relies on the `_update` mechanism * * Emits a {Transfer} event with `from` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead. */ function _mint(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidReceiver(address(0)); } _update(address(0), account, value); } /** * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply. * Relies on the `_update` mechanism. * * Emits a {Transfer} event with `to` set to the zero address. * * NOTE: This function is not virtual, {_update} should be overridden instead */ function _burn(address account, uint256 value) internal { if (account == address(0)) { revert ERC20InvalidSender(address(0)); } _update(account, address(0), value); } /** * @dev Sets `value` 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. * * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument. */ function _approve(address owner, address spender, uint256 value) internal { _approve(owner, spender, value, true); } /** * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event. * * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any * `Approval` event during `transferFrom` operations. * * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to * true using the following override: * ``` * function _approve(address owner, address spender, uint256 value, bool) internal virtual override { * super._approve(owner, spender, value, true); * } * ``` * * Requirements are the same as {_approve}. */ function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual { if (owner == address(0)) { revert ERC20InvalidApprover(address(0)); } if (spender == address(0)) { revert ERC20InvalidSpender(address(0)); } _allowances[owner][spender] = value; if (emitEvent) { emit Approval(owner, spender, value); } } /** * @dev Updates `owner` s allowance for `spender` based on spent `value`. * * Does not update the allowance value in case of infinite allowance. * Revert if not enough allowance is available. * * Does not emit an {Approval} event. */ function _spendAllowance(address owner, address spender, uint256 value) internal virtual { uint256 currentAllowance = allowance(owner, spender); if (currentAllowance != type(uint256).max) { if (currentAllowance < value) { revert ERC20InsufficientAllowance(spender, currentAllowance, value); } unchecked { _approve(owner, spender, currentAllowance - value, false); } } } } // File: @openzeppelin/contracts/access/Ownable.sol // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; /** * @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. * * The initial owner is set to the address provided by the deployer. 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 Ownable is Context { address private _owner; /** * @dev The caller account is not authorized to perform an operation. */ error OwnableUnauthorizedAccount(address account); /** * @dev The owner is not a valid owner account. (eg. `address(0)`) */ error OwnableInvalidOwner(address owner); event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the address provided by the deployer as the initial owner. */ constructor(address initialOwner) { if (initialOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(initialOwner); } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { _checkOwner(); _; } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if the sender is not the owner. */ function _checkOwner() internal view virtual { if (owner() != _msgSender()) { revert OwnableUnauthorizedAccount(_msgSender()); } } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby disabling any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(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 { if (newOwner == address(0)) { revert OwnableInvalidOwner(address(0)); } _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } } // File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol) pragma solidity ^0.8.20; /** * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612]. * * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't * need to send a transaction, and thus is not required to hold Ether at all. * * ==== Security Considerations * * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be * considered as an intention to spend the allowance in any specific way. The second is that because permits have * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be * generally recommended is: * * ```solidity * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public { * try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {} * doThing(..., value); * } * * function doThing(..., uint256 value) public { * token.safeTransferFrom(msg.sender, address(this), value); * ... * } * ``` * * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also * {SafeERC20-safeTransferFrom}). * * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so * contracts should have entry points that don't rely on permit. */ interface IERC20Permit { /** * @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]. * * CAUTION: See Security Considerations above. */ function permit( address owner, address spender, uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s ) external; /** * @dev Returns the current nonce for `owner`. This value must be * included whenever a signature is generated for {permit}. * * Every successful call to {permit} increases ``owner``'s nonce by one. This * prevents a signature from being used multiple times. */ function nonces(address owner) external view returns (uint256); /** * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}. */ // solhint-disable-next-line func-name-mixedcase function DOMAIN_SEPARATOR() external view returns (bytes32); } // File: @openzeppelin/contracts/utils/Address.sol // OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol) pragma solidity ^0.8.20; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev The ETH balance of the account is not enough to perform the operation. */ error AddressInsufficientBalance(address account); /** * @dev There's no code at `target` (it is not a contract). */ error AddressEmptyCode(address target); /** * @dev A call to an address target failed. The target may have reverted. */ error FailedInnerCall(); /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://consensys.net/diligence/blog/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { if (address(this).balance < amount) { revert AddressInsufficientBalance(address(this)); } (bool success, ) = recipient.call{value: amount}(""); if (!success) { revert FailedInnerCall(); } } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason or custom error, it is bubbled * up by this function (like regular Solidity function calls). However, if * the call reverted with no returned reason, this function reverts with a * {FailedInnerCall} error. * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCallWithValue(target, data, 0); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { if (address(this).balance < value) { revert AddressInsufficientBalance(address(this)); } (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResultFromTarget(target, success, returndata); } /** * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an * unsuccessful call. */ function verifyCallResultFromTarget( address target, bool success, bytes memory returndata ) internal view returns (bytes memory) { if (!success) { _revert(returndata); } else { // only check if target is a contract if the call was successful and the return data is empty // otherwise we already know that it was a contract if (returndata.length == 0 && target.code.length == 0) { revert AddressEmptyCode(target); } return returndata; } } /** * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the * revert reason or with a default {FailedInnerCall} error. */ function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) { if (!success) { _revert(returndata); } else { return returndata; } } /** * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}. */ function _revert(bytes memory returndata) private pure { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly /// @solidity memory-safe-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert FailedInnerCall(); } } } // File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.20; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; /** * @dev An operation with an ERC20 token failed. */ error SafeERC20FailedOperation(address token); /** * @dev Indicates a failed `decreaseAllowance` request. */ error SafeERC20FailedDecreaseAllowance(address spender, uint256 currentAllowance, uint256 requestedDecrease); /** * @dev Transfer `value` amount of `token` from the calling contract to `to`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeTransfer(IERC20 token, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transfer, (to, value))); } /** * @dev Transfer `value` amount of `token` from `from` to `to`, spending the approval given by `from` to the * calling contract. If `token` returns no value, non-reverting calls are assumed to be successful. */ function safeTransferFrom(IERC20 token, address from, address to, uint256 value) internal { _callOptionalReturn(token, abi.encodeCall(token.transferFrom, (from, to, value))); } /** * @dev Increase the calling contract's allowance toward `spender` by `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. */ function safeIncreaseAllowance(IERC20 token, address spender, uint256 value) internal { uint256 oldAllowance = token.allowance(address(this), spender); forceApprove(token, spender, oldAllowance + value); } /** * @dev Decrease the calling contract's allowance toward `spender` by `requestedDecrease`. If `token` returns no * value, non-reverting calls are assumed to be successful. */ function safeDecreaseAllowance(IERC20 token, address spender, uint256 requestedDecrease) internal { unchecked { uint256 currentAllowance = token.allowance(address(this), spender); if (currentAllowance < requestedDecrease) { revert SafeERC20FailedDecreaseAllowance(spender, currentAllowance, requestedDecrease); } forceApprove(token, spender, currentAllowance - requestedDecrease); } } /** * @dev Set the calling contract's allowance toward `spender` to `value`. If `token` returns no value, * non-reverting calls are assumed to be successful. Meant to be used with tokens that require the approval * to be set to zero before setting it to a non-zero value, such as USDT. */ function forceApprove(IERC20 token, address spender, uint256 value) internal { bytes memory approvalCall = abi.encodeCall(token.approve, (spender, value)); if (!_callOptionalReturnBool(token, approvalCall)) { _callOptionalReturn(token, abi.encodeCall(token.approve, (spender, 0))); _callOptionalReturn(token, approvalCall); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address-functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data); if (returndata.length != 0 && !abi.decode(returndata, (bool))) { revert SafeERC20FailedOperation(address(token)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). * * This is a variant of {_callOptionalReturn} that silents catches all reverts and returns a bool instead. */ function _callOptionalReturnBool(IERC20 token, bytes memory data) private returns (bool) { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We cannot use {Address-functionCall} here since this should return false // and not revert is the subcall reverts. (bool success, bytes memory returndata) = address(token).call(data); return success && (returndata.length == 0 || abi.decode(returndata, (bool))) && address(token).code.length > 0; } } // File: ShibaSanToken.sol pragma solidity ^0.8.26; /** * @title IUniswapV2Factory * @dev Interface for interacting with the Uniswap V2 Factory contract. */ interface IUniswapV2Factory { /** * @dev Creates a new trading pair for `tokenA` and `tokenB` if it does not already exist. * @param tokenA Address of the first token in the pair. * @param tokenB Address of the second token in the pair. * @return pair Address of the newly created pair. */ function createPair(address tokenA, address tokenB) external returns (address pair); /** * @dev Retrieves the address of the pair for `tokenA` and `tokenB`. * @param tokenA Address of the first token in the pair. * @param tokenB Address of the second token in the pair. * @return pair Address of the pair, or the zero address if the pair does not exist. */ function getPair(address tokenA, address tokenB) external view returns (address pair); } /** * @title IUniswapV2Router01 * @dev Interface for the Uniswap V2 Router contract. */ interface IUniswapV2Router01 { /** * @dev Returns the address of the Uniswap V2 Factory contract. * @return Address of the Uniswap V2 Factory contract. */ function factory() external pure returns (address); /** * @dev Returns the address of the Wrapped ETH (WETH) token. * @return Address of the WETH token. */ function WETH() external pure returns (address); } /** * @title IUniswapV2Router02 * @dev Extended interface for the Uniswap V2 Router contract, adding additional functionalities to IUniswapV2Router01. */ interface IUniswapV2Router02 is IUniswapV2Router01 { /** * @notice Adds liquidity to a token-ETH pair. * @dev Adds liquidity to a Uniswap pair consisting of an ERC20 token and ETH. * If liquidity is added for the first time, the token-ETH pair is created. * @param token Address of the ERC20 token. * @param desiredTokenAmount Amount of the token to add as liquidity. * @param minTokenAmount Minimum amount of the token to be added as liquidity. * @param minETHAmount Minimum amount of ETH to be added as liquidity. * @param to Address to receive the liquidity tokens. * @param deadline Unix timestamp after which the transaction will revert if not executed. * @return amountToken The amount of the token added as liquidity. * @return amountETH The amount of ETH added as liquidity. * @return liquidity The amount of liquidity tokens received. */ function addLiquidityETH( address token, uint256 desiredTokenAmount, uint256 minTokenAmount, uint256 minETHAmount, address to, uint256 deadline ) external payable returns (uint256 amountToken, uint256 amountETH, uint256 liquidity); /** * @notice Swaps an exact amount of tokens for ETH, supporting fee-on-transfer tokens. * @dev This function swaps an exact amount of input tokens for as many output tokens as possible, * supporting tokens with transfer fees. The path array determines the route of the swap. * @param amountIn Amount of input tokens to be sent. * @param amountOutMin Minimum amount of output ETH that must be received for the transaction not to revert. * @param path Array of token addresses. The first element is the input token, the last is the output token, * and any intermediate elements are pairs to trade through. * @param to Address to receive the output ETH. * @param deadline Unix timestamp after which the transaction will revert if not executed. */ function swapExactTokensForETHSupportingFeeOnTransferTokens( uint256 amountIn, uint256 amountOutMin, address[] calldata path, address to, uint256 deadline ) external; } /** * @title ShibaSanToken * @dev Implementation of the ShibaSanToken contract, extending the ERC20 standard with * Uniswap integration for liquidity and trading functionalities. * * This contract represents an ERC20 token with features to interact with Uniswap, * including setting up trading pairs and managing liquidity. */ contract ShibaSanToken is ERC20, Ownable { using SafeERC20 for IERC20; using Address for address payable; IUniswapV2Router02 public immutable dexRouter; address public immutable dexPair; address public marketingAddress = 0xc0F33f895bB8EdF56E7aa923dBCc987fDD09b1C0; // Address for receiving marketing funds address public constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD; // Address used for burning tokens uint256 public constant TOTAL_SUPPLY = 10_000_000_000 * 10**18; bool public tradingActive = false; // Indicates if trading is active bool public feesStopped = false; // Indicates if fees are halted uint256 public buyTotalFees = 2; // Total fees for buy transactions (2%) uint256 private _buyBurnFee = 1; // Burn fee for buy transactions (1%) uint256 private _buyMarketingFee = 1; // Marketing fee for buy transactions (1%) uint256 public sellTotalFees = 2; // Total fees for sell transactions (2%) uint256 private _sellBurnFee = 1; // Burn fee for sell transactions (1%) uint256 private _sellMarketingFee = 1; // Marketing fee for sell transactions (1%) uint256 public batchSize = 250; // Number of addresses processed per batch during airdrop uint256 public constant STOP_DEX_FEE_THRESHOLD = 1_000_000 * 10**18; // Stop fees when total supply is 1,000,000 tokens (with 18 decimal places mapping(address => bool) private _isExcludedFromFees; // Tracks addresses that are exempt from transaction fees mapping(address => bool) public uniswapPairs; // Records Uniswap pair addresses for this token mapping(address => uint256) public ethSent; // Logs the amount of ETH sent to each address event TradingEnabled(); // Emitted when trading is enabled for SHIBA token event UniswapPairUpdated(address indexed pair, bool isPair); // Emitted when a Uniswap pair is updated event LiquidityProvided(uint256 tokensSupplied, uint256 ethSupplied, uint256 liquidityTokens); // Emitted when liquidity is successfully added event FeesStopped(); // Emitted when DEX transaction fees are stopped for SHIBA token event ExcludeFromFees(address indexed account, bool isExcluded); // Emitted when an address is excluded from fees event MarketingAddressUpdated(address indexed newAddress, address indexed oldAddress); // Emitted when the marketing address is updated event ContractEthReceived(address indexed sender, uint256 amount); // Emitted when the contract receives ETH event ShibaTokenAirdropped(uint256 numOfRecipients, uint256 totalTokens); // Emitted when tokens are distributed in an airdrop event EthStuckWithdrawn(address indexed owner, uint256 amount); // Emitted when stuck ETH is withdrawn from the contract modifier tradingActiveRequired() { require(tradingActive, "Trading is not active."); // Ensures trading is active _; } constructor() ERC20("Shiba San", "SHIBA") Ownable(msg.sender) { uint256 ownerSupply = TOTAL_SUPPLY * 10 / 100; // 10% to owner uint256 marketingSupply = TOTAL_SUPPLY * 5 / 100; // 5% to marketing address uint256 contractSupply = TOTAL_SUPPLY * 85 / 100; // 85% to contract _buyMarketingFee = 1; // Set marketing fee for buy transactions to 1% _buyBurnFee = 1; // Set burn fee for buy transactions to 1% buyTotalFees = _buyMarketingFee + _buyBurnFee; // Calculate total buy fees (2%) _sellMarketingFee = 1; // Set marketing fee for sell transactions to 1% _sellBurnFee = 1; // Set burn fee for sell transactions to 1% sellTotalFees = _sellMarketingFee + _sellBurnFee; // Calculate total sell fees (2%) // Initialize the Uniswap V2 Router interface with the Uniswap Router address IUniswapV2Router02 _dexRouter = IUniswapV2Router02( 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D // Uniswap V2 Router address ); dexRouter = _dexRouter; // Create a Uniswap V2 Pair for this token and WETH dexPair = IUniswapV2Factory(_dexRouter.factory()) .createPair(address(this), _dexRouter.WETH()); // Approve the Uniswap Router to spend the maximum possible amount of tokens from this contract _approve(address(this), address(_dexRouter), type(uint256).max); // Mint tokens to the respective addresses _mint(msg.sender, ownerSupply); // Mint 10% to the owner _mint(marketingAddress, marketingSupply); // Mint 5% to the marketing address _mint(address(this), contractSupply); // Mint 85% to the contract address // Exclude specific addresses from fees excludeFromFees(owner(), true); // Exclude the owner address from fees excludeFromFees(address(this), true); // Exclude the contract address from fees excludeFromFees(BURN_ADDRESS, true); // Exclude the burn address from fees excludeFromFees(marketingAddress, true); // Exclude the marketing address from fees // Mark the newly created Uniswap pair as a Uniswap pair uniswapPairs[dexPair] = true; } /** * @notice Updates the batch size for airdrop operations. * @dev The batch size determines how many addresses will be processed in each batch during airdrops. * This helps manage gas usage and avoid hitting transaction limits when distributing tokens to multiple recipients. * @param _batchSize The new batch size to be set for airdrops. */ function setBatchSize(uint256 _batchSize) external onlyOwner { batchSize = _batchSize; // Update the batch size for airdrop operations } /** * @notice Enables trading for the SHIBA token. * @dev This function can only be called by the contract owner. It activates trading by setting the * `tradingActive` state variable to `true`. If trading is already active, the function will revert with an error. * Once trading is enabled, an event `TradingEnabled` is emitted to indicate the change in trading status. */ function enableTrading() external onlyOwner { // Ensure trading is not already active to avoid unnecessary state changes require(!tradingActive, "Trading already active."); // Set tradingActive to true to allow trading tradingActive = true; // Log the activation of trading through an event emit TradingEnabled(); } /** * @notice Adds liquidity to the Uniswap pool and burns the received LP tokens. * @dev This function can only be called by the contract owner. It requires trading to be active. * The function adds the contract's token and ETH balance to the liquidity pool, * and burns the received LP tokens by sending them to the burn address. * It also tracks the Uniswap pair if not already tracked. */ function provideLiquidity() external onlyOwner { // Ensure trading is active to prevent adding liquidity under undesirable conditions require(tradingActive, "Trading must be active to add liquidity."); // Get the contract's token and ETH balances to add to the liquidity pool uint256 contractTokenBalance = balanceOf(address(this)); uint256 ethBalance = address(this).balance; // Add liquidity to Uniswap and burn the received LP tokens (uint256 tokenAmount, uint256 ethAmount, uint256 liquidity) = dexRouter.addLiquidityETH{value: ethBalance}( address(this), // Token address contractTokenBalance, // Amount of tokens to add 0, // No minimum token amount (no slippage control) 0, // No minimum ETH amount (no slippage control) BURN_ADDRESS, // Send LP tokens to the burn address block.timestamp // Deadline for the transaction ); // Check if the Uniswap pair exists and track it if not already tracked address pair = IUniswapV2Factory(dexRouter.factory()).getPair(address(this), dexRouter.WETH()); if (pair != address(0)) { uniswapPairs[pair] = true; emit UniswapPairUpdated(pair, true); } // Emit an event to log the liquidity addition emit LiquidityProvided(tokenAmount, ethAmount, liquidity); } /** * @notice Withdraws LP tokens that are stuck in the contract and sends them to the owner. * @dev This function is used to recover any LP tokens that may have been inadvertently sent * to the contract or accumulated during liquidity provision. It ensures that there are LP tokens * available in the contract before attempting to transfer them. */ function withdrawStuckLPTokens() external onlyOwner { // Create an instance of the LP token contract using the LP pair address IERC20 lpToken = IERC20(dexPair); // Retrieve the balance of LP tokens held by this contract uint256 lpTokenBalance = lpToken.balanceOf(address(this)); // Ensure there are LP tokens available for withdrawal require(lpTokenBalance > 0, "No LP tokens to withdraw"); // Transfer the LP tokens to the owner's address lpToken.transfer(owner(), lpTokenBalance); } /** * @notice Handles the transfer of tokens between addresses. * @dev Applies fees during transactions involving Uniswap pairs (buys and sells). * The function: * - Checks if the transfer is occurring on Uniswap (buy/sell) or between regular wallet addresses. * - Applies and deducts fees for Uniswap transactions: * - **Buy:** Fees are calculated, tokens are burned, and marketing fees are converted to ETH and sent to the marketing address. * - **Sell:** Similar to buys, fees are calculated, tokens are burned, and marketing fees are converted to ETH and sent to the marketing address. * - Transfers tokens without fees for wallet-to-wallet transfers or transactions involving centralized exchanges. * @param from The address sending the tokens. * @param to The address receiving the tokens. * @param amount The amount of tokens to transfer. */ function _transferTokens(address from, address to, uint256 amount) internal { require(from != address(0), "Transfer from the zero address"); require(to != address(0), "Transfer to the zero address"); require(amount > 0, "Transfer amount must be greater than zero"); uint256 totalFees; uint256 burnAmount; uint256 marketingAmount; if (uniswapPairs[from] && !_isExcludedFromFees[to]) { // Buy require(tradingActive, "Trading is not active."); require(!feesStopped || amount <= STOP_DEX_FEE_THRESHOLD, "Fees have been stopped."); totalFees = (amount * buyTotalFees) / 100; burnAmount = (amount * _buyBurnFee) / 100; marketingAmount = totalFees - burnAmount; // Burn tokens super._transfer(from, BURN_ADDRESS, burnAmount); // Transfer tokens to contract for conversion super._transfer(from, address(this), marketingAmount); // Convert tokens to ETH and send to marketing address uint256 initialETHBalance = address(this).balance; swapTokensForEth(marketingAmount); // Convert tokens to ETH uint256 newETHBalance = address(this).balance; uint256 ethForMarketing = newETHBalance - initialETHBalance; // Send ETH to marketing address (bool success, ) = marketingAddress.call{value: ethForMarketing}(""); require(success, "ETH transfer to marketing failed."); // Transfer the remaining amount to the recipient super._transfer(from, to, amount - totalFees); } else if (uniswapPairs[to] && !_isExcludedFromFees[from]) { // Sell require(tradingActive, "Trading is not active."); require(!feesStopped || amount <= STOP_DEX_FEE_THRESHOLD, "Fees have been stopped."); totalFees = (amount * sellTotalFees) / 100; burnAmount = (amount * _sellBurnFee) / 100; marketingAmount = totalFees - burnAmount; // Burn tokens super._transfer(from, BURN_ADDRESS, burnAmount); // Transfer tokens to contract for conversion super._transfer(from, address(this), marketingAmount); // Convert tokens to ETH and send to marketing address uint256 initialETHBalance = address(this).balance; swapTokensForEth(marketingAmount); // Convert tokens to ETH uint256 newETHBalance = address(this).balance; uint256 ethForMarketing = newETHBalance - initialETHBalance; // Send ETH to marketing address (bool success, ) = marketingAddress.call{value: ethForMarketing}(""); require(success, "ETH transfer to marketing failed."); // Transfer the remaining amount to the recipient super._transfer(from, to, amount - totalFees); } else { // Normal transfer with no fees super._transfer(from, to, amount); } } /** * @notice Swaps a specified amount of tokens for ETH using Uniswap. * @dev This function uses Uniswap's `swapExactTokensForETHSupportingFeeOnTransferTokens` method to perform the swap. * It first approves the Uniswap router to spend the tokens and then executes the swap. * The function handles slippage by setting the minimum ETH amount to 0, meaning it does not account for slippage. * It returns `true` if the swap was successful and `false` if it failed. * @param tokenAmount The amount of tokens to swap for ETH. * @return success A boolean indicating if the swap was successful. */ function swapTokensForEth(uint256 tokenAmount) private returns (bool) { // Define the path for the swap: from token to ETH address[] memory path = new address[](2); path[0] = address(this); // Token address (this contract's token) path[1] = dexRouter.WETH(); // WETH address (Wrapped ETH) // Approve the Uniswap V2 router to spend the specified amount of tokens _approve(address(this), address(dexRouter), tokenAmount); // Attempt to swap the tokens for ETH try dexRouter.swapExactTokensForETHSupportingFeeOnTransferTokens( tokenAmount, // Amount of tokens to swap 0, // Minimum amount of ETH to receive (slippage not considered here) path, // Path for the swap (token -> ETH) address(this), // Address to receive the ETH (this contract) block.timestamp // Deadline for the transaction ) { return true; // Return true if the swap was successful } catch { return false; // Return false if the swap failed } } /** * @notice Stops fees if the total token supply is below or equal to the defined threshold. * @dev This function can be called by the owner to stop collecting fees on transactions when the total supply * of tokens falls to or below a predefined threshold. It sets the flag `feesStopped` to true and * zeroes out the buy and sell fees. It ensures that fees are not already stopped and that the * total supply is below the threshold before making changes. * * Requirements: * - Fees must not already be stopped. * - The total token supply must be less than or equal to the threshold defined by `STOP_DEX_FEE_THRESHOLD`. * * Emits a `FeesStopped` event when fees are successfully stopped. */ function stopDexFeesIfThresholdReached() external { // Ensure that fees are not already stopped require(!feesStopped, "Fees already stopped."); // Ensure that the total token supply is below or equal to the threshold require(totalSupply() <= STOP_DEX_FEE_THRESHOLD, "Total supply is greater than threshold."); // Set the flag to indicate that fees are stopped feesStopped = true; // Set buy and sell fees to zero buyTotalFees = 0; sellTotalFees = 0; // Emit an event to signal that fees have been stopped emit FeesStopped(); } /** * @notice Updates the fee exclusion status for a specific address. * @dev This function allows the owner to set an address as either excluded from fees or included in fees. * Excluded addresses will not be subject to transaction fees when buying or selling tokens. * * @param account The address to update the fee exclusion status for. * @param excluded A boolean indicating whether the address should be excluded from fees (true) or not (false). * * Emits an `ExcludeFromFees` event when the status of the address is updated. * * Requirements: * - The caller must be the owner of the contract. */ function excludeFromFees(address account, bool excluded) public onlyOwner { // Set the exclusion status for the specified address _isExcludedFromFees[account] = excluded; // Emit an event to notify that the exclusion status has been updated emit ExcludeFromFees(account, excluded); } /** * @notice Updates the marketing address for the contract. * @dev This function allows the owner to set a new address for receiving marketing funds. * The new address must be a valid, non-zero address. * * @param _marketingAddress The new marketing address to be set. * * Emits a `MarketingAddressUpdated` event when the marketing address is changed. * * Requirements: * - The caller must be the owner of the contract. * - The new marketing address cannot be the zero address. */ function setMarketingAddress(address _marketingAddress) external onlyOwner { // Ensure the new marketing address is not the zero address require(_marketingAddress != address(0), "Invalid marketing address"); // Store the old marketing address to use in the event emission address oldAddress = marketingAddress; // Update the marketing address to the new address marketingAddress = _marketingAddress; // Emit an event to log the change of the marketing address emit MarketingAddressUpdated(_marketingAddress, oldAddress); } /** * @notice Allows the contract to receive ETH. * @dev This function is triggered when ETH is sent directly to the contract address. * It emits an event to log the receipt of ETH. * * Emits a `ContractEthReceived` event with the sender's address and the amount of ETH received. */ receive() external payable { // Emit an event with the sender's address and the amount of ETH received emit ContractEthReceived(msg.sender, msg.value); } /** * @dev Returns the current ETH balance of the contract. * * This function is a view-only operation that allows anyone to check the contract's * ETH balance. It does not alter the contract's state or incur any gas costs for * external callers. * * @return The amount of ETH held by the contract, denominated in wei. * * @notice This function provides a way to view the available ETH in the contract * without making any changes to its state. It can be called by any address. */ function viewEthBalance() external view returns (uint256) { return address(this).balance; } /** * @notice Allows the contract owner to withdraw any stuck ETH from the contract. * @dev This function retrieves the contract's ETH balance and transfers it to the owner's address. * It ensures there is ETH available for withdrawal and emits an event upon successful transfer. * * Requirements: * - Only the contract owner can call this function. * - The contract must have a positive ETH balance. * * Emits an `EthStuckWithdrawn` event with the owner's address and the amount of ETH withdrawn. */ function withdrawStuckEth() external onlyOwner { // Retrieve the ETH balance of this contract uint256 ethBalance = address(this).balance; // Ensure there is ETH available to withdraw require(ethBalance > 0, "No ETH to withdraw"); // Attempt to transfer the ETH to the owner's address (bool success, ) = msg.sender.call{value: ethBalance}(""); // Ensure the ETH transfer was successful require(success, "Transfer failed."); // Emit an event to log the ETH withdrawal emit EthStuckWithdrawn(msg.sender, ethBalance); } /** * @notice Airdrops SHIBA tokens to a list of addresses. * @dev This function allows the contract owner to distribute SHIBA tokens to multiple addresses. * The airdrop is processed in batches to manage gas consumption effectively. * The function will revert if: * - The lengths of the `addresses` and `tokenAmounts` arrays do not match. * - The contract does not have enough SHIBA tokens to cover the total airdrop amount. * * After the airdrop is completed, a `ShibaTokenAirdropped` event is emitted indicating the * total number of addresses and tokens that were airdropped. * * @param addresses The list of recipient addresses. * @param tokenAmounts The corresponding list of token amounts to be airdropped to each address. */ function airdropShibaToken(address[] calldata addresses, uint256[] calldata tokenAmounts) external onlyOwner { // Ensure the lengths of the addresses and tokenAmounts arrays are equal require(addresses.length == tokenAmounts.length, "List length mismatch"); uint256 totalAddresses = addresses.length; // Number of addresses to airdrop tokens to uint256 airdropTotal = 0; // Total number of tokens to be airdropped // Calculate the total number of tokens to be distributed in the airdrop for (uint256 i = 0; i < totalAddresses; i++) { airdropTotal += tokenAmounts[i]; // Accumulate the total amount of tokens } // Ensure the contract has sufficient tokens to perform the airdrop require(balanceOf(address(this)) >= airdropTotal, "Token balance too low"); uint256 processed = 0; // Counter to track the number of processed addresses // Distribute tokens in batches to manage gas usage while (processed < totalAddresses) { uint256 end = processed + batchSize; // Calculate the end index for the current batch if (end > totalAddresses) { end = totalAddresses; // Ensure the end index does not exceed the total number of addresses } // Transfer tokens to each address in the current batch for (uint256 i = processed; i < end; i++) { _transfer(address(this), addresses[i], tokenAmounts[i]); // Perform the token transfer } processed = end; // Update the processed count to the end of the current batch } // Emit an event to log the completion of the airdrop process emit ShibaTokenAirdropped(totalAddresses, airdropTotal); } /** * @notice Withdraws any SHIBA tokens that are stuck in the contract. * @dev This function allows the owner to recover SHIBA tokens that may have accidentally been sent to the contract address. * It checks if the contract holds any SHIBA tokens and transfers them to the owner's address. * This function can only be called by the owner of the contract. * * Requirements: * - Only the contract owner can call this function. * - The contract must hold SHIBA tokens to withdraw. * * Emits a `Transfer` event to log the withdrawal of SHIBA tokens. */ function withdrawStuckShibaToken() external onlyOwner { // Retrieve the SHIBA token balance of this contract uint256 contractBalance = balanceOf(address(this)); // Ensure there are SHIBA tokens available to withdraw require(contractBalance > 0, "No SHIBA tokens to withdraw"); // Transfer all SHIBA tokens from this contract to the owner's address _transfer(address(this), msg.sender, contractBalance); } /** * @notice Burns a specified amount of SHIBA tokens from the contract's balance. * @dev This function permanently removes the specified amount of SHIBA tokens * from circulation by transferring them to the burn address. Only the contract * owner can call this function. * @param amount The number of SHIBA tokens to be burned. */ function burnShibaToken(uint256 amount) external onlyOwner { // Transfer the specified amount of SHIBA tokens to the burn address _transfer(address(this), BURN_ADDRESS, amount); } /** * @notice Updates the status of a Uniswap pair address in the contract. * @dev This function allows the owner to mark an address as a Uniswap pair or not. * This can be useful for adjusting the contract's behavior based on the trading pair status. * The function updates the `uniswapPairs` mapping and emits an event to log the change. * * Requirements: * - Only the contract owner can call this function. * * @param pair The address of the Uniswap pair to be updated. * @param isPair A boolean indicating whether the address should be marked as a Uniswap pair (`true`) or not (`false`). * Emits an `UniswapPairUpdated` event to log the update. */ function updateUniswapPair(address pair, bool isPair) external onlyOwner { // Update the mapping to reflect the new status of the Uniswap pair uniswapPairs[pair] = isPair; // Emit an event to log the update emit UniswapPairUpdated(pair, isPair); } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"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":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ContractEthReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"EthStuckWithdrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"bool","name":"isExcluded","type":"bool"}],"name":"ExcludeFromFees","type":"event"},{"anonymous":false,"inputs":[],"name":"FeesStopped","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokensSupplied","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"ethSupplied","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"liquidityTokens","type":"uint256"}],"name":"LiquidityProvided","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"newAddress","type":"address"},{"indexed":true,"internalType":"address","name":"oldAddress","type":"address"}],"name":"MarketingAddressUpdated","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":"numOfRecipients","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"totalTokens","type":"uint256"}],"name":"ShibaTokenAirdropped","type":"event"},{"anonymous":false,"inputs":[],"name":"TradingEnabled","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"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"pair","type":"address"},{"indexed":false,"internalType":"bool","name":"isPair","type":"bool"}],"name":"UniswapPairUpdated","type":"event"},{"inputs":[],"name":"BURN_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STOP_DEX_FEE_THRESHOLD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOTAL_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"tokenAmounts","type":"uint256[]"}],"name":"airdropShibaToken","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":"value","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"batchSize","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnShibaToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"buyTotalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dexPair","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dexRouter","outputs":[{"internalType":"contract IUniswapV2Router02","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"ethSent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"bool","name":"excluded","type":"bool"}],"name":"excludeFromFees","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feesStopped","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"marketingAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"provideLiquidity","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"sellTotalFees","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_batchSize","type":"uint256"}],"name":"setBatchSize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_marketingAddress","type":"address"}],"name":"setMarketingAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"stopDexFeesIfThresholdReached","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"value","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":"","type":"address"}],"name":"uniswapPairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"},{"internalType":"bool","name":"isPair","type":"bool"}],"name":"updateUniswapPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"viewEthBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawStuckEth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawStuckLPTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawStuckShibaToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60c060405273c0f33f895bb8edf56e7aa923dbcc987fdd09b1c060065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505f600660146101000a81548160ff0219169083151502179055505f600660156101000a81548160ff0219169083151502179055506002600755600160085560016009556002600a556001600b556001600c5560fa600d553480156100ba575f80fd5b50336040518060400160405280600981526020017f53686962612053616e00000000000000000000000000000000000000000000008152506040518060400160405280600581526020017f534849424100000000000000000000000000000000000000000000000000000081525081600390816101379190610eb4565b5080600490816101479190610eb4565b5050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036101ba575f6040517f1e4fbdf70000000000000000000000000000000000000000000000000000000081526004016101b19190610fc2565b60405180910390fd5b6101c9816105b660201b60201c565b505f6064600a6b204fce5e3e250261100000006101e69190611008565b6101f09190611076565b90505f606460056b204fce5e3e2502611000000061020e9190611008565b6102189190611076565b90505f606460556b204fce5e3e250261100000006102369190611008565b6102409190611076565b90506001600981905550600160088190555060085460095461026291906110a6565b6007819055506001600c819055506001600b81905550600b54600c5461028891906110a6565b600a819055505f737a250d5630b4cf539739df2c5dacb4c659f2488d90508073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff16815250508073ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610323573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103479190611107565b73ffffffffffffffffffffffffffffffffffffffff1663c9c65396308373ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa1580156103ac573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906103d09190611107565b6040518363ffffffff1660e01b81526004016103ed929190611132565b6020604051808303815f875af1158015610409573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061042d9190611107565b73ffffffffffffffffffffffffffffffffffffffff1660a08173ffffffffffffffffffffffffffffffffffffffff168152505061049130827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff61067960201b60201c565b6104a1338561069160201b60201c565b6104d260065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff168461069160201b60201c565b6104e2308361069160201b60201c565b6105006104f361071660201b60201c565b600161073e60201b60201c565b61051130600161073e60201b60201c565b61052461dead600161073e60201b60201c565b61055660065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16600161073e60201b60201c565b6001600f5f60a05173ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff021916908315150217905550505050506111e9565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b61068c83838360016107f260201b60201c565b505050565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610701575f6040517fec442f050000000000000000000000000000000000000000000000000000000081526004016106f89190610fc2565b60405180910390fd5b6107125f83836109c160201b60201c565b5050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b61074c610bda60201b60201c565b80600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff167f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df7826040516107e69190611173565b60405180910390a25050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603610862575f6040517fe602df050000000000000000000000000000000000000000000000000000000081526004016108599190610fc2565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036108d2575f6040517f94280d620000000000000000000000000000000000000000000000000000000081526004016108c99190610fc2565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f208190555080156109bb578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516109b2919061119b565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a11578060025f828254610a0591906110a6565b92505081905550610adf565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015610a9a578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401610a91939291906111b4565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610b26578060025f8282540392505081905550610b70565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051610bcd919061119b565b60405180910390a3505050565b610be8610c7360201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16610c0c61071660201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614610c7157610c35610c7360201b60201c565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401610c689190610fc2565b60405180910390fd5b565b5f33905090565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680610cf557607f821691505b602082108103610d0857610d07610cb1565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f60088302610d6a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82610d2f565b610d748683610d2f565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f610db8610db3610dae84610d8c565b610d95565b610d8c565b9050919050565b5f819050919050565b610dd183610d9e565b610de5610ddd82610dbf565b848454610d3b565b825550505050565b5f90565b610df9610ded565b610e04818484610dc8565b505050565b5b81811015610e2757610e1c5f82610df1565b600181019050610e0a565b5050565b601f821115610e6c57610e3d81610d0e565b610e4684610d20565b81016020851015610e55578190505b610e69610e6185610d20565b830182610e09565b50505b505050565b5f82821c905092915050565b5f610e8c5f1984600802610e71565b1980831691505092915050565b5f610ea48383610e7d565b9150826002028217905092915050565b610ebd82610c7a565b67ffffffffffffffff811115610ed657610ed5610c84565b5b610ee08254610cde565b610eeb828285610e2b565b5f60209050601f831160018114610f1c575f8415610f0a578287015190505b610f148582610e99565b865550610f7b565b601f198416610f2a86610d0e565b5f5b82811015610f5157848901518255600182019150602085019450602081019050610f2c565b86831015610f6e5784890151610f6a601f891682610e7d565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f610fac82610f83565b9050919050565b610fbc81610fa2565b82525050565b5f602082019050610fd55f830184610fb3565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f61101282610d8c565b915061101d83610d8c565b925082820261102b81610d8c565b9150828204841483151761104257611041610fdb565b5b5092915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601260045260245ffd5b5f61108082610d8c565b915061108b83610d8c565b92508261109b5761109a611049565b5b828204905092915050565b5f6110b082610d8c565b91506110bb83610d8c565b92508282019050808211156110d3576110d2610fdb565b5b92915050565b5f80fd5b6110e681610fa2565b81146110f0575f80fd5b50565b5f81519050611101816110dd565b92915050565b5f6020828403121561111c5761111b6110d9565b5b5f611129848285016110f3565b91505092915050565b5f6040820190506111455f830185610fb3565b6111526020830184610fb3565b9392505050565b5f8115159050919050565b61116d81611159565b82525050565b5f6020820190506111865f830184611164565b92915050565b61119581610d8c565b82525050565b5f6020820190506111ae5f83018461118c565b92915050565b5f6060820190506111c75f830186610fb3565b6111d4602083018561118c565b6111e1604083018461118c565b949350505050565b60805160a051612e486112265f395f81816117a4015261190b01525f818161093301528181610c6e01528181610d1c0152610dc50152612e485ff3fe608060405260043610610228575f3560e01c80638da5cb5b11610122578063d54f2fec116100aa578063f242ab411161006e578063f242ab41146107d1578063f2fde38b146107fb578063f31c0f1f14610823578063f4daaba11461084d578063fccc2813146108775761027d565b8063d54f2fec14610703578063d85ba0631461072b578063db0f315114610755578063dd62ed3e1461077f578063ed735d9a146107bb5761027d565b806395d89b41116100f157806395d89b4114610621578063a5ece9411461064b578063a9059cbb14610675578063bbc0c742146106b1578063c0246668146106db5761027d565b80638da5cb5b1461057b578063902d55a5146105a5578063906e9dd0146105cf578063918213d0146105f75761027d565b8063449a1d55116101b05780636a486a8e116101745780636a486a8e146104d357806370a08231146104fd578063715018a6146105395780637fa787ba1461054f5780638a8c523c146105655761027d565b8063449a1d5514610407578063576f35e3146104435780635d37c71b1461046b57806360c97b221461048157806367e00e88146104975761027d565b806318160ddd116101f757806318160ddd1461032757806323b872dd146103515780632e8ec8551461038d578063313ce567146103b5578063428b1025146103df5761027d565b806306fdde03146102815780630758d924146102ab578063095ea7b3146102d55780630baf90b5146103115761027d565b3661027d573373ffffffffffffffffffffffffffffffffffffffff167f9a6b8a4fca5da9adcc6323a2edc8f403ac9add42b93a47bc49bcd70ce6329ee73460405161027391906120a9565b60405180910390a2005b5f80fd5b34801561028c575f80fd5b506102956108a1565b6040516102a29190612132565b60405180910390f35b3480156102b6575f80fd5b506102bf610931565b6040516102cc91906121cc565b60405180910390f35b3480156102e0575f80fd5b506102fb60048036038101906102f69190612252565b610955565b60405161030891906122aa565b60405180910390f35b34801561031c575f80fd5b50610325610977565b005b348015610332575f80fd5b5061033b6109db565b60405161034891906120a9565b60405180910390f35b34801561035c575f80fd5b50610377600480360381019061037291906122c3565b6109e4565b60405161038491906122aa565b60405180910390f35b348015610398575f80fd5b506103b360048036038101906103ae9190612313565b610a12565b005b3480156103c0575f80fd5b506103c9610a2a565b6040516103d69190612359565b60405180910390f35b3480156103ea575f80fd5b506104056004803603810190610400919061239c565b610a32565b005b348015610412575f80fd5b5061042d600480360381019061042891906123da565b610ae0565b60405161043a91906120a9565b60405180910390f35b34801561044e575f80fd5b5061046960048036038101906104649190612313565b610af5565b005b348015610476575f80fd5b5061047f610b07565b005b34801561048c575f80fd5b50610495610c02565b005b3480156104a2575f80fd5b506104bd60048036038101906104b891906123da565b610fc9565b6040516104ca91906122aa565b60405180910390f35b3480156104de575f80fd5b506104e7610fe6565b6040516104f491906120a9565b60405180910390f35b348015610508575f80fd5b50610523600480360381019061051e91906123da565b610fec565b60405161053091906120a9565b60405180910390f35b348015610544575f80fd5b5061054d611031565b005b34801561055a575f80fd5b50610563611044565b005b348015610570575f80fd5b5061057961118c565b005b348015610586575f80fd5b5061058f61122d565b60405161059c9190612414565b60405180910390f35b3480156105b0575f80fd5b506105b9611255565b6040516105c691906120a9565b60405180910390f35b3480156105da575f80fd5b506105f560048036038101906105f091906123da565b611265565b005b348015610602575f80fd5b5061060b61139e565b60405161061891906120a9565b60405180910390f35b34801561062c575f80fd5b506106356113ac565b6040516106429190612132565b60405180910390f35b348015610656575f80fd5b5061065f61143c565b60405161066c9190612414565b60405180910390f35b348015610680575f80fd5b5061069b60048036038101906106969190612252565b611461565b6040516106a891906122aa565b60405180910390f35b3480156106bc575f80fd5b506106c5611483565b6040516106d291906122aa565b60405180910390f35b3480156106e6575f80fd5b5061070160048036038101906106fc919061239c565b611496565b005b34801561070e575f80fd5b50610729600480360381019061072491906124e3565b611544565b005b348015610736575f80fd5b5061073f6116fe565b60405161074c91906120a9565b60405180910390f35b348015610760575f80fd5b50610769611704565b60405161077691906122aa565b60405180910390f35b34801561078a575f80fd5b506107a560048036038101906107a09190612561565b611717565b6040516107b291906120a9565b60405180910390f35b3480156107c6575f80fd5b506107cf611799565b005b3480156107dc575f80fd5b506107e5611909565b6040516107f29190612414565b60405180910390f35b348015610806575f80fd5b50610821600480360381019061081c91906123da565b61192d565b005b34801561082e575f80fd5b506108376119b1565b60405161084491906120a9565b60405180910390f35b348015610858575f80fd5b506108616119b8565b60405161086e91906120a9565b60405180910390f35b348015610882575f80fd5b5061088b6119be565b6040516108989190612414565b60405180910390f35b6060600380546108b0906125cc565b80601f01602080910402602001604051908101604052809291908181526020018280546108dc906125cc565b80156109275780601f106108fe57610100808354040283529160200191610927565b820191905f5260205f20905b81548152906001019060200180831161090a57829003601f168201915b5050505050905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b5f8061095f6119c4565b905061096c8185856119cb565b600191505092915050565b61097f6119dd565b5f61098930610fec565b90505f81116109cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c490612646565b60405180910390fd5b6109d8303383611a64565b50565b5f600254905090565b5f806109ee6119c4565b90506109fb858285611b54565b610a06858585611a64565b60019150509392505050565b610a1a6119dd565b610a273061dead83611a64565b50565b5f6012905090565b610a3a6119dd565b80600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff167f28dac15f34de71abfdd8ff0e58c27b3f931762749b421b6df750dc2d8afcb6f582604051610ad491906122aa565b60405180910390a25050565b6010602052805f5260405f205f915090505481565b610afd6119dd565b80600d8190555050565b600660159054906101000a900460ff1615610b57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4e906126ae565b60405180910390fd5b69d3c21bcecceda1000000610b6a6109db565b1115610bab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba29061273c565b60405180910390fd5b6001600660156101000a81548160ff0219169083151502179055505f6007819055505f600a819055507f0cc823ac7dcbb71f71c9fd26579d770400f72b22c87e3493783bb2dc360ae00260405160405180910390a1565b610c0a6119dd565b600660149054906101000a900460ff16610c59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c50906127ca565b60405180910390fd5b5f610c6330610fec565b90505f4790505f805f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663f305d7198530885f8061dead426040518863ffffffff1660e01b8152600401610cd296959493929190612821565b60606040518083038185885af1158015610cee573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610d139190612894565b9250925092505f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da791906128f8565b73ffffffffffffffffffffffffffffffffffffffff1663e6a43905307f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e2c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e5091906128f8565b6040518363ffffffff1660e01b8152600401610e6d929190612923565b602060405180830381865afa158015610e88573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eac91906128f8565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f86576001600f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f28dac15f34de71abfdd8ff0e58c27b3f931762749b421b6df750dc2d8afcb6f56001604051610f7d91906122aa565b60405180910390a25b7faa58f006cc244b2af6662862508bd39465f57169ff8386d1d1f7b0b903150abc848484604051610fb99392919061294a565b60405180910390a1505050505050565b600f602052805f5260405f205f915054906101000a900460ff1681565b600a5481565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6110396119dd565b6110425f611be6565b565b61104c6119dd565b5f4790505f8111611092576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611089906129c9565b60405180910390fd5b5f3373ffffffffffffffffffffffffffffffffffffffff16826040516110b790612a14565b5f6040518083038185875af1925050503d805f81146110f1576040519150601f19603f3d011682016040523d82523d5f602084013e6110f6565b606091505b505090508061113a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113190612a72565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f3be8b6049fc79847d899ee4a8cb394fe72a7e08ca0cd364cb383ec9b8dbcc2ba8360405161118091906120a9565b60405180910390a25050565b6111946119dd565b600660149054906101000a900460ff16156111e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111db90612ada565b60405180910390fd5b6001600660146101000a81548160ff0219169083151502179055507f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c760405160405180910390a1565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6b204fce5e3e2502611000000081565b61126d6119dd565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d290612b42565b60405180910390fd5b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fa8efc72ed34f90017df79620d1972d42b8e3b17eb0077fc5fc46cbf1a19ed9a960405160405180910390a35050565b69d3c21bcecceda100000081565b6060600480546113bb906125cc565b80601f01602080910402602001604051908101604052809291908181526020018280546113e7906125cc565b80156114325780601f1061140957610100808354040283529160200191611432565b820191905f5260205f20905b81548152906001019060200180831161141557829003601f168201915b5050505050905090565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8061146b6119c4565b9050611478818585611a64565b600191505092915050565b600660149054906101000a900460ff1681565b61149e6119dd565b80600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff167f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df78260405161153891906122aa565b60405180910390a25050565b61154c6119dd565b818190508484905014611594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158b90612baa565b60405180910390fd5b5f8484905090505f805b828110156115da578484828181106115b9576115b8612bc8565b5b90506020020135826115cb9190612c22565b9150808060010191505061159e565b50806115e530610fec565b1015611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90612c9f565b60405180910390fd5b5f5b828110156116bc575f600d548261163f9190612c22565b90508381111561164d578390505b5f8290505b818110156116b2576116a5308a8a8481811061167157611670612bc8565b5b905060200201602081019061168691906123da565b89898581811061169957611698612bc8565b5b90506020020135611a64565b8080600101915050611652565b5080915050611628565b7f36175ec88dfba3c6d11a82da1987c8892696a016f2fd2e0377d958378f14875783836040516116ed929190612cbd565b60405180910390a150505050505050565b60075481565b600660159054906101000a900460ff1681565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6117a16119dd565b5f7f000000000000000000000000000000000000000000000000000000000000000090505f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016117ff9190612414565b602060405180830381865afa15801561181a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061183e9190612ce4565b90505f8111611882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187990612d59565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6118a661122d565b836040518363ffffffff1660e01b81526004016118c4929190612d77565b6020604051808303815f875af11580156118e0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119049190612db2565b505050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6119356119dd565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119a5575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161199c9190612414565b60405180910390fd5b6119ae81611be6565b50565b5f47905090565b600d5481565b61dead81565b5f33905090565b6119d88383836001611ca9565b505050565b6119e56119c4565b73ffffffffffffffffffffffffffffffffffffffff16611a0361122d565b73ffffffffffffffffffffffffffffffffffffffff1614611a6257611a266119c4565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611a599190612414565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ad4575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611acb9190612414565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b44575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611b3b9190612414565b60405180910390fd5b611b4f838383611e78565b505050565b5f611b5f8484611717565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611be05781811015611bd1578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611bc893929190612ddd565b60405180910390fd5b611bdf84848484035f611ca9565b5b50505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611d19575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401611d109190612414565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d89575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611d809190612414565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611e72578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611e6991906120a9565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ec8578060025f828254611ebc9190612c22565b92505081905550611f96565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611f51578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611f4893929190612ddd565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611fdd578060025f8282540392505081905550612027565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161208491906120a9565b60405180910390a3505050565b5f819050919050565b6120a381612091565b82525050565b5f6020820190506120bc5f83018461209a565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612104826120c2565b61210e81856120cc565b935061211e8185602086016120dc565b612127816120ea565b840191505092915050565b5f6020820190508181035f83015261214a81846120fa565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f61219461218f61218a84612152565b612171565b612152565b9050919050565b5f6121a58261217a565b9050919050565b5f6121b68261219b565b9050919050565b6121c6816121ac565b82525050565b5f6020820190506121df5f8301846121bd565b92915050565b5f80fd5b5f80fd5b5f6121f782612152565b9050919050565b612207816121ed565b8114612211575f80fd5b50565b5f81359050612222816121fe565b92915050565b61223181612091565b811461223b575f80fd5b50565b5f8135905061224c81612228565b92915050565b5f8060408385031215612268576122676121e5565b5b5f61227585828601612214565b92505060206122868582860161223e565b9150509250929050565b5f8115159050919050565b6122a481612290565b82525050565b5f6020820190506122bd5f83018461229b565b92915050565b5f805f606084860312156122da576122d96121e5565b5b5f6122e786828701612214565b93505060206122f886828701612214565b92505060406123098682870161223e565b9150509250925092565b5f60208284031215612328576123276121e5565b5b5f6123358482850161223e565b91505092915050565b5f60ff82169050919050565b6123538161233e565b82525050565b5f60208201905061236c5f83018461234a565b92915050565b61237b81612290565b8114612385575f80fd5b50565b5f8135905061239681612372565b92915050565b5f80604083850312156123b2576123b16121e5565b5b5f6123bf85828601612214565b92505060206123d085828601612388565b9150509250929050565b5f602082840312156123ef576123ee6121e5565b5b5f6123fc84828501612214565b91505092915050565b61240e816121ed565b82525050565b5f6020820190506124275f830184612405565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261244e5761244d61242d565b5b8235905067ffffffffffffffff81111561246b5761246a612431565b5b60208301915083602082028301111561248757612486612435565b5b9250929050565b5f8083601f8401126124a3576124a261242d565b5b8235905067ffffffffffffffff8111156124c0576124bf612431565b5b6020830191508360208202830111156124dc576124db612435565b5b9250929050565b5f805f80604085870312156124fb576124fa6121e5565b5b5f85013567ffffffffffffffff811115612518576125176121e9565b5b61252487828801612439565b9450945050602085013567ffffffffffffffff811115612547576125466121e9565b5b6125538782880161248e565b925092505092959194509250565b5f8060408385031215612577576125766121e5565b5b5f61258485828601612214565b925050602061259585828601612214565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806125e357607f821691505b6020821081036125f6576125f561259f565b5b50919050565b7f4e6f20534849424120746f6b656e7320746f20776974686472617700000000005f82015250565b5f612630601b836120cc565b915061263b826125fc565b602082019050919050565b5f6020820190508181035f83015261265d81612624565b9050919050565b7f4665657320616c72656164792073746f707065642e00000000000000000000005f82015250565b5f6126986015836120cc565b91506126a382612664565b602082019050919050565b5f6020820190508181035f8301526126c58161268c565b9050919050565b7f546f74616c20737570706c792069732067726561746572207468616e207468725f8201527f6573686f6c642e00000000000000000000000000000000000000000000000000602082015250565b5f6127266027836120cc565b9150612731826126cc565b604082019050919050565b5f6020820190508181035f8301526127538161271a565b9050919050565b7f54726164696e67206d7573742062652061637469766520746f20616464206c695f8201527f717569646974792e000000000000000000000000000000000000000000000000602082015250565b5f6127b46028836120cc565b91506127bf8261275a565b604082019050919050565b5f6020820190508181035f8301526127e1816127a8565b9050919050565b5f819050919050565b5f61280b612806612801846127e8565b612171565b612091565b9050919050565b61281b816127f1565b82525050565b5f60c0820190506128345f830189612405565b612841602083018861209a565b61284e6040830187612812565b61285b6060830186612812565b6128686080830185612405565b61287560a083018461209a565b979650505050505050565b5f8151905061288e81612228565b92915050565b5f805f606084860312156128ab576128aa6121e5565b5b5f6128b886828701612880565b93505060206128c986828701612880565b92505060406128da86828701612880565b9150509250925092565b5f815190506128f2816121fe565b92915050565b5f6020828403121561290d5761290c6121e5565b5b5f61291a848285016128e4565b91505092915050565b5f6040820190506129365f830185612405565b6129436020830184612405565b9392505050565b5f60608201905061295d5f83018661209a565b61296a602083018561209a565b612977604083018461209a565b949350505050565b7f4e6f2045544820746f20776974686472617700000000000000000000000000005f82015250565b5f6129b36012836120cc565b91506129be8261297f565b602082019050919050565b5f6020820190508181035f8301526129e0816129a7565b9050919050565b5f81905092915050565b50565b5f6129ff5f836129e7565b9150612a0a826129f1565b5f82019050919050565b5f612a1e826129f4565b9150819050919050565b7f5472616e73666572206661696c65642e000000000000000000000000000000005f82015250565b5f612a5c6010836120cc565b9150612a6782612a28565b602082019050919050565b5f6020820190508181035f830152612a8981612a50565b9050919050565b7f54726164696e6720616c7265616479206163746976652e0000000000000000005f82015250565b5f612ac46017836120cc565b9150612acf82612a90565b602082019050919050565b5f6020820190508181035f830152612af181612ab8565b9050919050565b7f496e76616c6964206d61726b6574696e672061646472657373000000000000005f82015250565b5f612b2c6019836120cc565b9150612b3782612af8565b602082019050919050565b5f6020820190508181035f830152612b5981612b20565b9050919050565b7f4c697374206c656e677468206d69736d617463680000000000000000000000005f82015250565b5f612b946014836120cc565b9150612b9f82612b60565b602082019050919050565b5f6020820190508181035f830152612bc181612b88565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612c2c82612091565b9150612c3783612091565b9250828201905080821115612c4f57612c4e612bf5565b5b92915050565b7f546f6b656e2062616c616e636520746f6f206c6f7700000000000000000000005f82015250565b5f612c896015836120cc565b9150612c9482612c55565b602082019050919050565b5f6020820190508181035f830152612cb681612c7d565b9050919050565b5f604082019050612cd05f83018561209a565b612cdd602083018461209a565b9392505050565b5f60208284031215612cf957612cf86121e5565b5b5f612d0684828501612880565b91505092915050565b7f4e6f204c5020746f6b656e7320746f20776974686472617700000000000000005f82015250565b5f612d436018836120cc565b9150612d4e82612d0f565b602082019050919050565b5f6020820190508181035f830152612d7081612d37565b9050919050565b5f604082019050612d8a5f830185612405565b612d97602083018461209a565b9392505050565b5f81519050612dac81612372565b92915050565b5f60208284031215612dc757612dc66121e5565b5b5f612dd484828501612d9e565b91505092915050565b5f606082019050612df05f830186612405565b612dfd602083018561209a565b612e0a604083018461209a565b94935050505056fea264697066735822122038fb86a8a5032b2ed2c0d4550e4e02c76f8aff274285238fc5860aaa999f820664736f6c634300081a0033
Deployed Bytecode
0x608060405260043610610228575f3560e01c80638da5cb5b11610122578063d54f2fec116100aa578063f242ab411161006e578063f242ab41146107d1578063f2fde38b146107fb578063f31c0f1f14610823578063f4daaba11461084d578063fccc2813146108775761027d565b8063d54f2fec14610703578063d85ba0631461072b578063db0f315114610755578063dd62ed3e1461077f578063ed735d9a146107bb5761027d565b806395d89b41116100f157806395d89b4114610621578063a5ece9411461064b578063a9059cbb14610675578063bbc0c742146106b1578063c0246668146106db5761027d565b80638da5cb5b1461057b578063902d55a5146105a5578063906e9dd0146105cf578063918213d0146105f75761027d565b8063449a1d55116101b05780636a486a8e116101745780636a486a8e146104d357806370a08231146104fd578063715018a6146105395780637fa787ba1461054f5780638a8c523c146105655761027d565b8063449a1d5514610407578063576f35e3146104435780635d37c71b1461046b57806360c97b221461048157806367e00e88146104975761027d565b806318160ddd116101f757806318160ddd1461032757806323b872dd146103515780632e8ec8551461038d578063313ce567146103b5578063428b1025146103df5761027d565b806306fdde03146102815780630758d924146102ab578063095ea7b3146102d55780630baf90b5146103115761027d565b3661027d573373ffffffffffffffffffffffffffffffffffffffff167f9a6b8a4fca5da9adcc6323a2edc8f403ac9add42b93a47bc49bcd70ce6329ee73460405161027391906120a9565b60405180910390a2005b5f80fd5b34801561028c575f80fd5b506102956108a1565b6040516102a29190612132565b60405180910390f35b3480156102b6575f80fd5b506102bf610931565b6040516102cc91906121cc565b60405180910390f35b3480156102e0575f80fd5b506102fb60048036038101906102f69190612252565b610955565b60405161030891906122aa565b60405180910390f35b34801561031c575f80fd5b50610325610977565b005b348015610332575f80fd5b5061033b6109db565b60405161034891906120a9565b60405180910390f35b34801561035c575f80fd5b50610377600480360381019061037291906122c3565b6109e4565b60405161038491906122aa565b60405180910390f35b348015610398575f80fd5b506103b360048036038101906103ae9190612313565b610a12565b005b3480156103c0575f80fd5b506103c9610a2a565b6040516103d69190612359565b60405180910390f35b3480156103ea575f80fd5b506104056004803603810190610400919061239c565b610a32565b005b348015610412575f80fd5b5061042d600480360381019061042891906123da565b610ae0565b60405161043a91906120a9565b60405180910390f35b34801561044e575f80fd5b5061046960048036038101906104649190612313565b610af5565b005b348015610476575f80fd5b5061047f610b07565b005b34801561048c575f80fd5b50610495610c02565b005b3480156104a2575f80fd5b506104bd60048036038101906104b891906123da565b610fc9565b6040516104ca91906122aa565b60405180910390f35b3480156104de575f80fd5b506104e7610fe6565b6040516104f491906120a9565b60405180910390f35b348015610508575f80fd5b50610523600480360381019061051e91906123da565b610fec565b60405161053091906120a9565b60405180910390f35b348015610544575f80fd5b5061054d611031565b005b34801561055a575f80fd5b50610563611044565b005b348015610570575f80fd5b5061057961118c565b005b348015610586575f80fd5b5061058f61122d565b60405161059c9190612414565b60405180910390f35b3480156105b0575f80fd5b506105b9611255565b6040516105c691906120a9565b60405180910390f35b3480156105da575f80fd5b506105f560048036038101906105f091906123da565b611265565b005b348015610602575f80fd5b5061060b61139e565b60405161061891906120a9565b60405180910390f35b34801561062c575f80fd5b506106356113ac565b6040516106429190612132565b60405180910390f35b348015610656575f80fd5b5061065f61143c565b60405161066c9190612414565b60405180910390f35b348015610680575f80fd5b5061069b60048036038101906106969190612252565b611461565b6040516106a891906122aa565b60405180910390f35b3480156106bc575f80fd5b506106c5611483565b6040516106d291906122aa565b60405180910390f35b3480156106e6575f80fd5b5061070160048036038101906106fc919061239c565b611496565b005b34801561070e575f80fd5b50610729600480360381019061072491906124e3565b611544565b005b348015610736575f80fd5b5061073f6116fe565b60405161074c91906120a9565b60405180910390f35b348015610760575f80fd5b50610769611704565b60405161077691906122aa565b60405180910390f35b34801561078a575f80fd5b506107a560048036038101906107a09190612561565b611717565b6040516107b291906120a9565b60405180910390f35b3480156107c6575f80fd5b506107cf611799565b005b3480156107dc575f80fd5b506107e5611909565b6040516107f29190612414565b60405180910390f35b348015610806575f80fd5b50610821600480360381019061081c91906123da565b61192d565b005b34801561082e575f80fd5b506108376119b1565b60405161084491906120a9565b60405180910390f35b348015610858575f80fd5b506108616119b8565b60405161086e91906120a9565b60405180910390f35b348015610882575f80fd5b5061088b6119be565b6040516108989190612414565b60405180910390f35b6060600380546108b0906125cc565b80601f01602080910402602001604051908101604052809291908181526020018280546108dc906125cc565b80156109275780601f106108fe57610100808354040283529160200191610927565b820191905f5260205f20905b81548152906001019060200180831161090a57829003601f168201915b5050505050905090565b7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d81565b5f8061095f6119c4565b905061096c8185856119cb565b600191505092915050565b61097f6119dd565b5f61098930610fec565b90505f81116109cd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109c490612646565b60405180910390fd5b6109d8303383611a64565b50565b5f600254905090565b5f806109ee6119c4565b90506109fb858285611b54565b610a06858585611a64565b60019150509392505050565b610a1a6119dd565b610a273061dead83611a64565b50565b5f6012905090565b610a3a6119dd565b80600f5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff167f28dac15f34de71abfdd8ff0e58c27b3f931762749b421b6df750dc2d8afcb6f582604051610ad491906122aa565b60405180910390a25050565b6010602052805f5260405f205f915090505481565b610afd6119dd565b80600d8190555050565b600660159054906101000a900460ff1615610b57576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4e906126ae565b60405180910390fd5b69d3c21bcecceda1000000610b6a6109db565b1115610bab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ba29061273c565b60405180910390fd5b6001600660156101000a81548160ff0219169083151502179055505f6007819055505f600a819055507f0cc823ac7dcbb71f71c9fd26579d770400f72b22c87e3493783bb2dc360ae00260405160405180910390a1565b610c0a6119dd565b600660149054906101000a900460ff16610c59576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c50906127ca565b60405180910390fd5b5f610c6330610fec565b90505f4790505f805f7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663f305d7198530885f8061dead426040518863ffffffff1660e01b8152600401610cd296959493929190612821565b60606040518083038185885af1158015610cee573d5f803e3d5ffd5b50505050506040513d601f19601f82011682018060405250810190610d139190612894565b9250925092505f7f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663c45a01556040518163ffffffff1660e01b8152600401602060405180830381865afa158015610d83573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610da791906128f8565b73ffffffffffffffffffffffffffffffffffffffff1663e6a43905307f0000000000000000000000007a250d5630b4cf539739df2c5dacb4c659f2488d73ffffffffffffffffffffffffffffffffffffffff1663ad5c46486040518163ffffffff1660e01b8152600401602060405180830381865afa158015610e2c573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610e5091906128f8565b6040518363ffffffff1660e01b8152600401610e6d929190612923565b602060405180830381865afa158015610e88573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610eac91906128f8565b90505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610f86576001600f5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508073ffffffffffffffffffffffffffffffffffffffff167f28dac15f34de71abfdd8ff0e58c27b3f931762749b421b6df750dc2d8afcb6f56001604051610f7d91906122aa565b60405180910390a25b7faa58f006cc244b2af6662862508bd39465f57169ff8386d1d1f7b0b903150abc848484604051610fb99392919061294a565b60405180910390a1505050505050565b600f602052805f5260405f205f915054906101000a900460ff1681565b600a5481565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b6110396119dd565b6110425f611be6565b565b61104c6119dd565b5f4790505f8111611092576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611089906129c9565b60405180910390fd5b5f3373ffffffffffffffffffffffffffffffffffffffff16826040516110b790612a14565b5f6040518083038185875af1925050503d805f81146110f1576040519150601f19603f3d011682016040523d82523d5f602084013e6110f6565b606091505b505090508061113a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161113190612a72565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff167f3be8b6049fc79847d899ee4a8cb394fe72a7e08ca0cd364cb383ec9b8dbcc2ba8360405161118091906120a9565b60405180910390a25050565b6111946119dd565b600660149054906101000a900460ff16156111e4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111db90612ada565b60405180910390fd5b6001600660146101000a81548160ff0219169083151502179055507f799663458a5ef2936f7fa0c99b3336c69c25890f82974f04e811e5bb359186c760405160405180910390a1565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6b204fce5e3e2502611000000081565b61126d6119dd565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036112db576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112d290612b42565b60405180910390fd5b5f60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160065f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fa8efc72ed34f90017df79620d1972d42b8e3b17eb0077fc5fc46cbf1a19ed9a960405160405180910390a35050565b69d3c21bcecceda100000081565b6060600480546113bb906125cc565b80601f01602080910402602001604051908101604052809291908181526020018280546113e7906125cc565b80156114325780601f1061140957610100808354040283529160200191611432565b820191905f5260205f20905b81548152906001019060200180831161141557829003601f168201915b5050505050905090565b60065f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1681565b5f8061146b6119c4565b9050611478818585611a64565b600191505092915050565b600660149054906101000a900460ff1681565b61149e6119dd565b80600e5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff167f9d8f7706ea1113d1a167b526eca956215946dd36cc7df39eb16180222d8b5df78260405161153891906122aa565b60405180910390a25050565b61154c6119dd565b818190508484905014611594576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161158b90612baa565b60405180910390fd5b5f8484905090505f805b828110156115da578484828181106115b9576115b8612bc8565b5b90506020020135826115cb9190612c22565b9150808060010191505061159e565b50806115e530610fec565b1015611626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161d90612c9f565b60405180910390fd5b5f5b828110156116bc575f600d548261163f9190612c22565b90508381111561164d578390505b5f8290505b818110156116b2576116a5308a8a8481811061167157611670612bc8565b5b905060200201602081019061168691906123da565b89898581811061169957611698612bc8565b5b90506020020135611a64565b8080600101915050611652565b5080915050611628565b7f36175ec88dfba3c6d11a82da1987c8892696a016f2fd2e0377d958378f14875783836040516116ed929190612cbd565b60405180910390a150505050505050565b60075481565b600660159054906101000a900460ff1681565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6117a16119dd565b5f7f00000000000000000000000023610141634ddfea415e82b580db68285e4e116d90505f8173ffffffffffffffffffffffffffffffffffffffff166370a08231306040518263ffffffff1660e01b81526004016117ff9190612414565b602060405180830381865afa15801561181a573d5f803e3d5ffd5b505050506040513d601f19601f8201168201806040525081019061183e9190612ce4565b90505f8111611882576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187990612d59565b60405180910390fd5b8173ffffffffffffffffffffffffffffffffffffffff1663a9059cbb6118a661122d565b836040518363ffffffff1660e01b81526004016118c4929190612d77565b6020604051808303815f875af11580156118e0573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906119049190612db2565b505050565b7f00000000000000000000000023610141634ddfea415e82b580db68285e4e116d81565b6119356119dd565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119a5575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040161199c9190612414565b60405180910390fd5b6119ae81611be6565b50565b5f47905090565b600d5481565b61dead81565b5f33905090565b6119d88383836001611ca9565b505050565b6119e56119c4565b73ffffffffffffffffffffffffffffffffffffffff16611a0361122d565b73ffffffffffffffffffffffffffffffffffffffff1614611a6257611a266119c4565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611a599190612414565b60405180910390fd5b565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ad4575f6040517f96c6fd1e000000000000000000000000000000000000000000000000000000008152600401611acb9190612414565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611b44575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611b3b9190612414565b60405180910390fd5b611b4f838383611e78565b505050565b5f611b5f8484611717565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114611be05781811015611bd1578281836040517ffb8f41b2000000000000000000000000000000000000000000000000000000008152600401611bc893929190612ddd565b60405180910390fd5b611bdf84848484035f611ca9565b5b50505050565b5f60055f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160055f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611d19575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401611d109190612414565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d89575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611d809190612414565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611e72578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611e6991906120a9565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611ec8578060025f828254611ebc9190612c22565b92505081905550611f96565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611f51578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611f4893929190612ddd565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611fdd578060025f8282540392505081905550612027565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161208491906120a9565b60405180910390a3505050565b5f819050919050565b6120a381612091565b82525050565b5f6020820190506120bc5f83018461209a565b92915050565b5f81519050919050565b5f82825260208201905092915050565b8281835e5f83830152505050565b5f601f19601f8301169050919050565b5f612104826120c2565b61210e81856120cc565b935061211e8185602086016120dc565b612127816120ea565b840191505092915050565b5f6020820190508181035f83015261214a81846120fa565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f819050919050565b5f61219461218f61218a84612152565b612171565b612152565b9050919050565b5f6121a58261217a565b9050919050565b5f6121b68261219b565b9050919050565b6121c6816121ac565b82525050565b5f6020820190506121df5f8301846121bd565b92915050565b5f80fd5b5f80fd5b5f6121f782612152565b9050919050565b612207816121ed565b8114612211575f80fd5b50565b5f81359050612222816121fe565b92915050565b61223181612091565b811461223b575f80fd5b50565b5f8135905061224c81612228565b92915050565b5f8060408385031215612268576122676121e5565b5b5f61227585828601612214565b92505060206122868582860161223e565b9150509250929050565b5f8115159050919050565b6122a481612290565b82525050565b5f6020820190506122bd5f83018461229b565b92915050565b5f805f606084860312156122da576122d96121e5565b5b5f6122e786828701612214565b93505060206122f886828701612214565b92505060406123098682870161223e565b9150509250925092565b5f60208284031215612328576123276121e5565b5b5f6123358482850161223e565b91505092915050565b5f60ff82169050919050565b6123538161233e565b82525050565b5f60208201905061236c5f83018461234a565b92915050565b61237b81612290565b8114612385575f80fd5b50565b5f8135905061239681612372565b92915050565b5f80604083850312156123b2576123b16121e5565b5b5f6123bf85828601612214565b92505060206123d085828601612388565b9150509250929050565b5f602082840312156123ef576123ee6121e5565b5b5f6123fc84828501612214565b91505092915050565b61240e816121ed565b82525050565b5f6020820190506124275f830184612405565b92915050565b5f80fd5b5f80fd5b5f80fd5b5f8083601f84011261244e5761244d61242d565b5b8235905067ffffffffffffffff81111561246b5761246a612431565b5b60208301915083602082028301111561248757612486612435565b5b9250929050565b5f8083601f8401126124a3576124a261242d565b5b8235905067ffffffffffffffff8111156124c0576124bf612431565b5b6020830191508360208202830111156124dc576124db612435565b5b9250929050565b5f805f80604085870312156124fb576124fa6121e5565b5b5f85013567ffffffffffffffff811115612518576125176121e9565b5b61252487828801612439565b9450945050602085013567ffffffffffffffff811115612547576125466121e9565b5b6125538782880161248e565b925092505092959194509250565b5f8060408385031215612577576125766121e5565b5b5f61258485828601612214565b925050602061259585828601612214565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806125e357607f821691505b6020821081036125f6576125f561259f565b5b50919050565b7f4e6f20534849424120746f6b656e7320746f20776974686472617700000000005f82015250565b5f612630601b836120cc565b915061263b826125fc565b602082019050919050565b5f6020820190508181035f83015261265d81612624565b9050919050565b7f4665657320616c72656164792073746f707065642e00000000000000000000005f82015250565b5f6126986015836120cc565b91506126a382612664565b602082019050919050565b5f6020820190508181035f8301526126c58161268c565b9050919050565b7f546f74616c20737570706c792069732067726561746572207468616e207468725f8201527f6573686f6c642e00000000000000000000000000000000000000000000000000602082015250565b5f6127266027836120cc565b9150612731826126cc565b604082019050919050565b5f6020820190508181035f8301526127538161271a565b9050919050565b7f54726164696e67206d7573742062652061637469766520746f20616464206c695f8201527f717569646974792e000000000000000000000000000000000000000000000000602082015250565b5f6127b46028836120cc565b91506127bf8261275a565b604082019050919050565b5f6020820190508181035f8301526127e1816127a8565b9050919050565b5f819050919050565b5f61280b612806612801846127e8565b612171565b612091565b9050919050565b61281b816127f1565b82525050565b5f60c0820190506128345f830189612405565b612841602083018861209a565b61284e6040830187612812565b61285b6060830186612812565b6128686080830185612405565b61287560a083018461209a565b979650505050505050565b5f8151905061288e81612228565b92915050565b5f805f606084860312156128ab576128aa6121e5565b5b5f6128b886828701612880565b93505060206128c986828701612880565b92505060406128da86828701612880565b9150509250925092565b5f815190506128f2816121fe565b92915050565b5f6020828403121561290d5761290c6121e5565b5b5f61291a848285016128e4565b91505092915050565b5f6040820190506129365f830185612405565b6129436020830184612405565b9392505050565b5f60608201905061295d5f83018661209a565b61296a602083018561209a565b612977604083018461209a565b949350505050565b7f4e6f2045544820746f20776974686472617700000000000000000000000000005f82015250565b5f6129b36012836120cc565b91506129be8261297f565b602082019050919050565b5f6020820190508181035f8301526129e0816129a7565b9050919050565b5f81905092915050565b50565b5f6129ff5f836129e7565b9150612a0a826129f1565b5f82019050919050565b5f612a1e826129f4565b9150819050919050565b7f5472616e73666572206661696c65642e000000000000000000000000000000005f82015250565b5f612a5c6010836120cc565b9150612a6782612a28565b602082019050919050565b5f6020820190508181035f830152612a8981612a50565b9050919050565b7f54726164696e6720616c7265616479206163746976652e0000000000000000005f82015250565b5f612ac46017836120cc565b9150612acf82612a90565b602082019050919050565b5f6020820190508181035f830152612af181612ab8565b9050919050565b7f496e76616c6964206d61726b6574696e672061646472657373000000000000005f82015250565b5f612b2c6019836120cc565b9150612b3782612af8565b602082019050919050565b5f6020820190508181035f830152612b5981612b20565b9050919050565b7f4c697374206c656e677468206d69736d617463680000000000000000000000005f82015250565b5f612b946014836120cc565b9150612b9f82612b60565b602082019050919050565b5f6020820190508181035f830152612bc181612b88565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52603260045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612c2c82612091565b9150612c3783612091565b9250828201905080821115612c4f57612c4e612bf5565b5b92915050565b7f546f6b656e2062616c616e636520746f6f206c6f7700000000000000000000005f82015250565b5f612c896015836120cc565b9150612c9482612c55565b602082019050919050565b5f6020820190508181035f830152612cb681612c7d565b9050919050565b5f604082019050612cd05f83018561209a565b612cdd602083018461209a565b9392505050565b5f60208284031215612cf957612cf86121e5565b5b5f612d0684828501612880565b91505092915050565b7f4e6f204c5020746f6b656e7320746f20776974686472617700000000000000005f82015250565b5f612d436018836120cc565b9150612d4e82612d0f565b602082019050919050565b5f6020820190508181035f830152612d7081612d37565b9050919050565b5f604082019050612d8a5f830185612405565b612d97602083018461209a565b9392505050565b5f81519050612dac81612372565b92915050565b5f60208284031215612dc757612dc66121e5565b5b5f612dd484828501612d9e565b91505092915050565b5f606082019050612df05f830186612405565b612dfd602083018561209a565b612e0a604083018461209a565b94935050505056fea264697066735822122038fb86a8a5032b2ed2c0d4550e4e02c76f8aff274285238fc5860aaa999f820664736f6c634300081a0033
Deployed Bytecode Sourcemap
46265:26769:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;65724:10;65704:42;;;65736:9;65704:42;;;;;;:::i;:::-;;;;;;;;46265:26769;;;;;13297:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46388:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;15590:190;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70925:483;;;;;;;;;;;;;:::i;:::-;;14399:99;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;16358:249;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71792:202;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;14250:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;72733:298;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47906:42;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;51830:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62390:646;;;;;;;;;;;;;:::i;:::-;;53227:1441;;;;;;;;;;;;;:::i;:::-;;47806:44;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47189:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14561:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;24972:103;;;;;;;;;;;;;:::i;:::-;;66999:650;;;;;;;;;;;;;:::i;:::-;;52396:386;;;;;;;;;;;;;:::i;:::-;;24297:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46730:62;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64623:621;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47538:67;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13507:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46481:76;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;14884:182;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46801:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63726:326;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68476:1820;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46947:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46875;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;15129:142;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55063:591;;;;;;;;;;;;;:::i;:::-;;46440:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;25230:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66318:105;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;47437:30;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;46605:81;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;13297:91;13342:13;13375:5;13368:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13297:91;:::o;46388:45::-;;;:::o;15590:190::-;15663:4;15680:13;15696:12;:10;:12::i;:::-;15680:28;;15719:31;15728:5;15735:7;15744:5;15719:8;:31::i;:::-;15768:4;15761:11;;;15590:190;;;;:::o;70925:483::-;24183:13;:11;:13::i;:::-;71052:23:::1;71078:24;71096:4;71078:9;:24::i;:::-;71052:50;;71213:1;71195:15;:19;71187:59;;;;;;;;;;;;:::i;:::-;;;;;;;;;71347:53;71365:4;71372:10;71384:15;71347:9;:53::i;:::-;70979:429;70925:483::o:0;14399:99::-;14451:7;14478:12;;14471:19;;14399:99;:::o;16358:249::-;16445:4;16462:15;16480:12;:10;:12::i;:::-;16462:30;;16503:37;16519:4;16525:7;16534:5;16503:15;:37::i;:::-;16551:26;16561:4;16567:2;16571:5;16551:9;:26::i;:::-;16595:4;16588:11;;;16358:249;;;;;:::o;71792:202::-;24183:13;:11;:13::i;:::-;71940:46:::1;71958:4;46644:42;71979:6;71940:9;:46::i;:::-;71792:202:::0;:::o;14250:84::-;14299:5;14324:2;14317:9;;14250:84;:::o;72733:298::-;24183:13;:11;:13::i;:::-;72915:6:::1;72894:12;:18;72907:4;72894:18;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;73010:4;72991:32;;;73016:6;72991:32;;;;;;:::i;:::-;;;;;;;;72733:298:::0;;:::o;47906:42::-;;;;;;;;;;;;;;;;;:::o;51830:150::-;24183:13;:11;:13::i;:::-;51914:10:::1;51902:9;:22;;;;51830:150:::0;:::o;62390:646::-;62513:11;;;;;;;;;;;62512:12;62504:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;47587:18;62661:13;:11;:13::i;:::-;:39;;62653:91;;;;;;;;;;;;:::i;:::-;;;;;;;;;62830:4;62816:11;;:18;;;;;;;;;;;;;;;;;;62904:1;62889:12;:16;;;;62932:1;62916:13;:17;;;;63015:13;;;;;;;;;;62390:646::o;53227:1441::-;24183:13;:11;:13::i;:::-;53387::::1;;;;;;;;;;;53379:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;53541:28;53572:24;53590:4;53572:9;:24::i;:::-;53541:55;;53607:18;53628:21;53607:42;;53732:19;53753:17:::0;53772::::1;53793:9;:25;;;53826:10;53860:4;53897:20;53959:1;54024::::0;46644:42:::1;54152:15;53793:417;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;53731:479;;;;;;54304:12;54337:9;:17;;;:19;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54319:46;;;54374:4;54381:9;:14;;;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54319:79;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;54304:94;;54429:1;54413:18;;:4;:18;;;54409:126;;54469:4;54448:12;:18;54461:4;54448:18;;;;;;;;;;;;;;;;:25;;;;;;;;;;;;;;;;;;54512:4;54493:30;;;54518:4;54493:30;;;;;;:::i;:::-;;;;;;;;54409:126;54608:52;54626:11;54639:9;54650;54608:52;;;;;;;;:::i;:::-;;;;;;;;53274:1394;;;;;;53227:1441::o:0;47806:44::-;;;;;;;;;;;;;;;;;;;;;;:::o;47189:32::-;;;;:::o;14561:118::-;14626:7;14653:9;:18;14663:7;14653:18;;;;;;;;;;;;;;;;14646:25;;14561:118;;;:::o;24972:103::-;24183:13;:11;:13::i;:::-;25037:30:::1;25064:1;25037:18;:30::i;:::-;24972:103::o:0;66999:650::-;24183:13;:11;:13::i;:::-;67111:18:::1;67132:21;67111:42;;67249:1;67236:10;:14;67228:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;67358:12;67376:10;:15;;67399:10;67376:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67357:57;;;67494:7;67486:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;67618:10;67600:41;;;67630:10;67600:41;;;;;;:::i;:::-;;;;;;;;67046:603;;66999:650::o:0;52396:386::-;24183:13;:11;:13::i;:::-;52544::::1;;;;;;;;;;;52543:14;52535:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;52677:4;52661:13;;:20;;;;;;;;;;;;;;;;;;52758:16;;;;;;;;;;52396:386::o:0;24297:87::-;24343:7;24370:6;;;;;;;;;;;24363:13;;24297:87;:::o;46730:62::-;46769:23;46730:62;:::o;64623:621::-;24183:13;:11;:13::i;:::-;64815:1:::1;64786:31;;:17;:31;;::::0;64778:69:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;64941:18;64962:16;;;;;;;;;;;64941:37;;65070:17;65051:16;;:36;;;;;;;;;;;;;;;;;;65225:10;65182:54;;65206:17;65182:54;;;;;;;;;;;;64698:546;64623:621:::0;:::o;47538:67::-;47587:18;47538:67;:::o;13507:95::-;13554:13;13587:7;13580:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13507:95;:::o;46481:76::-;;;;;;;;;;;;;:::o;14884:182::-;14953:4;14970:13;14986:12;:10;:12::i;:::-;14970:28;;15009:27;15019:5;15026:2;15030:5;15009:9;:27::i;:::-;15054:4;15047:11;;;14884:182;;;;:::o;46801:33::-;;;;;;;;;;;;;:::o;63726:326::-;24183:13;:11;:13::i;:::-;63905:8:::1;63874:19;:28;63894:7;63874:28;;;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;;;;64026:7;64010:34;;;64035:8;64010:34;;;;;;:::i;:::-;;;;;;;;63726:326:::0;;:::o;68476:1820::-;24183:13;:11;:13::i;:::-;68706:12:::1;;:19;;68686:9;;:16;;:39;68678:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;68763:22;68788:9;;:16;;68763:41;;68859:20;69026:9:::0;69021:144:::1;69045:14;69041:1;:18;69021:144;;;69097:12;;69110:1;69097:15;;;;;;;:::i;:::-;;;;;;;;69081:31;;;;;:::i;:::-;;;69061:3;;;;;;;69021:144;;;;69298:12;69270:24;69288:4;69270:9;:24::i;:::-;:40;;69262:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;69349:17;69498:652;69517:14;69505:9;:26;69498:652;;;69548:11;69574:9;;69562;:21;;;;:::i;:::-;69548:35;;69657:14;69651:3;:20;69647:151;;;69698:14;69692:20;;69647:151;69888:9;69900;69888:21;;69883:162;69915:3;69911:1;:7;69883:162;;;69944:55;69962:4;69969:9;;69979:1;69969:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;69983;;69996:1;69983:15;;;;;;;:::i;:::-;;;;;;;;69944:9;:55::i;:::-;69920:3;;;;;;;69883:162;;;;70073:3;70061:15;;69533:617;69498:652;;;70238:50;70259:14;70275:12;70238:50;;;;;;;:::i;:::-;;;;;;;;68585:1711;;;68476:1820:::0;;;;:::o;46947:31::-;;;;:::o;46875:::-;;;;;;;;;;;;;:::o;15129:142::-;15209:7;15236:11;:18;15248:5;15236:18;;;;;;;;;;;;;;;:27;15255:7;15236:27;;;;;;;;;;;;;;;;15229:34;;15129:142;;;;:::o;55063:591::-;24183:13;:11;:13::i;:::-;55208:14:::1;55232:7;55208:32;;55329:22;55354:7;:17;;;55380:4;55354:32;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;55329:57;;55496:1;55479:14;:18;55471:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;55605:7;:16;;;55622:7;:5;:7::i;:::-;55631:14;55605:41;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;55115:539;;55063:591::o:0;46440:32::-;;;:::o;25230:220::-;24183:13;:11;:13::i;:::-;25335:1:::1;25315:22;;:8;:22;;::::0;25311:93:::1;;25389:1;25361:31;;;;;;;;;;;:::i;:::-;;;;;;;;25311:93;25414:28;25433:8;25414:18;:28::i;:::-;25230:220:::0;:::o;66318:105::-;66367:7;66394:21;66387:28;;66318:105;:::o;47437:30::-;;;;:::o;46605:81::-;46644:42;46605:81;:::o;4302:98::-;4355:7;4382:10;4375:17;;4302:98;:::o;20417:130::-;20502:37;20511:5;20518:7;20527:5;20534:4;20502:8;:37::i;:::-;20417:130;;;:::o;24462:166::-;24533:12;:10;:12::i;:::-;24522:23;;:7;:5;:7::i;:::-;:23;;;24518:103;;24596:12;:10;:12::i;:::-;24569:40;;;;;;;;;;;:::i;:::-;;;;;;;;24518:103;24462:166::o;16992:308::-;17092:1;17076:18;;:4;:18;;;17072:88;;17145:1;17118:30;;;;;;;;;;;:::i;:::-;;;;;;;;17072:88;17188:1;17174:16;;:2;:16;;;17170:88;;17243:1;17214:32;;;;;;;;;;;:::i;:::-;;;;;;;;17170:88;17268:24;17276:4;17282:2;17286:5;17268:7;:24::i;:::-;16992:308;;;:::o;22133:487::-;22233:24;22260:25;22270:5;22277:7;22260:9;:25::i;:::-;22233:52;;22320:17;22300:16;:37;22296:317;;22377:5;22358:16;:24;22354:132;;;22437:7;22446:16;22464:5;22410:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;22354:132;22529:57;22538:5;22545:7;22573:5;22554:16;:24;22580:5;22529:8;:57::i;:::-;22296:317;22222:398;22133:487;;;:::o;25610:191::-;25684:16;25703:6;;;;;;;;;;;25684:25;;25729:8;25720:6;;:17;;;;;;;;;;;;;;;;;;25784:8;25753:40;;25774:8;25753:40;;;;;;;;;;;;25673:128;25610:191;:::o;21398:443::-;21528:1;21511:19;;:5;:19;;;21507:91;;21583:1;21554:32;;;;;;;;;;;:::i;:::-;;;;;;;;21507:91;21631:1;21612:21;;:7;:21;;;21608:92;;21685:1;21657:31;;;;;;;;;;;:::i;:::-;;;;;;;;21608:92;21740:5;21710:11;:18;21722:5;21710:18;;;;;;;;;;;;;;;:27;21729:7;21710:27;;;;;;;;;;;;;;;:35;;;;21760:9;21756:78;;;21807:7;21791:31;;21800:5;21791:31;;;21816:5;21791:31;;;;;;:::i;:::-;;;;;;;;21756:78;21398:443;;;;:::o;17624:1135::-;17730:1;17714:18;;:4;:18;;;17710:552;;17868:5;17852:12;;:21;;;;;;;:::i;:::-;;;;;;;;17710:552;;;17906:19;17928:9;:15;17938:4;17928:15;;;;;;;;;;;;;;;;17906:37;;17976:5;17962:11;:19;17958:117;;;18034:4;18040:11;18053:5;18009:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;17958:117;18230:5;18216:11;:19;18198:9;:15;18208:4;18198:15;;;;;;;;;;;;;;;:37;;;;17891:371;17710:552;18292:1;18278:16;;:2;:16;;;18274:435;;18460:5;18444:12;;:21;;;;;;;;;;;18274:435;;;18677:5;18660:9;:13;18670:2;18660:13;;;;;;;;;;;;;;;;:22;;;;;;;;;;;18274:435;18741:2;18726:25;;18735:4;18726:25;;;18745:5;18726:25;;;;;;:::i;:::-;;;;;;;;17624:1135;;;:::o;7:77:1:-;44:7;73:5;62:16;;7:77;;;:::o;90:118::-;177:24;195:5;177:24;:::i;:::-;172:3;165:37;90:118;;:::o;214:222::-;307:4;345:2;334:9;330:18;322:26;;358:71;426:1;415:9;411:17;402:6;358:71;:::i;:::-;214:222;;;;:::o;442:99::-;494:6;528:5;522:12;512:22;;442:99;;;:::o;547:169::-;631:11;665:6;660:3;653:19;705:4;700:3;696:14;681:29;;547:169;;;;:::o;722:139::-;811:6;806:3;801;795:23;852:1;843:6;838:3;834:16;827:27;722:139;;;:::o;867:102::-;908:6;959:2;955:7;950:2;943:5;939:14;935:28;925:38;;867:102;;;:::o;975:377::-;1063:3;1091:39;1124:5;1091:39;:::i;:::-;1146:71;1210:6;1205:3;1146:71;:::i;:::-;1139:78;;1226:65;1284:6;1279:3;1272:4;1265:5;1261:16;1226:65;:::i;:::-;1316:29;1338:6;1316:29;:::i;:::-;1311:3;1307:39;1300:46;;1067:285;975:377;;;;:::o;1358:313::-;1471:4;1509:2;1498:9;1494:18;1486:26;;1558:9;1552:4;1548:20;1544:1;1533:9;1529:17;1522:47;1586:78;1659:4;1650:6;1586:78;:::i;:::-;1578:86;;1358:313;;;;:::o;1677:126::-;1714:7;1754:42;1747:5;1743:54;1732:65;;1677:126;;;:::o;1809:60::-;1837:3;1858:5;1851:12;;1809:60;;;:::o;1875:142::-;1925:9;1958:53;1976:34;1985:24;2003:5;1985:24;:::i;:::-;1976:34;:::i;:::-;1958:53;:::i;:::-;1945:66;;1875:142;;;:::o;2023:126::-;2073:9;2106:37;2137:5;2106:37;:::i;:::-;2093:50;;2023:126;;;:::o;2155:153::-;2232:9;2265:37;2296:5;2265:37;:::i;:::-;2252:50;;2155:153;;;:::o;2314:185::-;2428:64;2486:5;2428:64;:::i;:::-;2423:3;2416:77;2314:185;;:::o;2505:276::-;2625:4;2663:2;2652:9;2648:18;2640:26;;2676:98;2771:1;2760:9;2756:17;2747:6;2676:98;:::i;:::-;2505:276;;;;:::o;2868:117::-;2977:1;2974;2967:12;2991:117;3100:1;3097;3090:12;3114:96;3151:7;3180:24;3198:5;3180:24;:::i;:::-;3169:35;;3114:96;;;:::o;3216:122::-;3289:24;3307:5;3289:24;:::i;:::-;3282:5;3279:35;3269:63;;3328:1;3325;3318:12;3269:63;3216:122;:::o;3344:139::-;3390:5;3428:6;3415:20;3406:29;;3444:33;3471:5;3444:33;:::i;:::-;3344:139;;;;:::o;3489:122::-;3562:24;3580:5;3562:24;:::i;:::-;3555:5;3552:35;3542:63;;3601:1;3598;3591:12;3542:63;3489:122;:::o;3617:139::-;3663:5;3701:6;3688:20;3679:29;;3717:33;3744:5;3717:33;:::i;:::-;3617:139;;;;:::o;3762:474::-;3830:6;3838;3887:2;3875:9;3866:7;3862:23;3858:32;3855:119;;;3893:79;;:::i;:::-;3855:119;4013:1;4038:53;4083:7;4074:6;4063:9;4059:22;4038:53;:::i;:::-;4028:63;;3984:117;4140:2;4166:53;4211:7;4202:6;4191:9;4187:22;4166:53;:::i;:::-;4156:63;;4111:118;3762:474;;;;;:::o;4242:90::-;4276:7;4319:5;4312:13;4305:21;4294:32;;4242:90;;;:::o;4338:109::-;4419:21;4434:5;4419:21;:::i;:::-;4414:3;4407:34;4338:109;;:::o;4453:210::-;4540:4;4578:2;4567:9;4563:18;4555:26;;4591:65;4653:1;4642:9;4638:17;4629:6;4591:65;:::i;:::-;4453:210;;;;:::o;4669:619::-;4746:6;4754;4762;4811:2;4799:9;4790:7;4786:23;4782:32;4779:119;;;4817:79;;:::i;:::-;4779:119;4937:1;4962:53;5007:7;4998:6;4987:9;4983:22;4962:53;:::i;:::-;4952:63;;4908:117;5064:2;5090:53;5135:7;5126:6;5115:9;5111:22;5090:53;:::i;:::-;5080:63;;5035:118;5192:2;5218:53;5263:7;5254:6;5243:9;5239:22;5218:53;:::i;:::-;5208:63;;5163:118;4669:619;;;;;:::o;5294:329::-;5353:6;5402:2;5390:9;5381:7;5377:23;5373:32;5370:119;;;5408:79;;:::i;:::-;5370:119;5528:1;5553:53;5598:7;5589:6;5578:9;5574:22;5553:53;:::i;:::-;5543:63;;5499:117;5294:329;;;;:::o;5629:86::-;5664:7;5704:4;5697:5;5693:16;5682:27;;5629:86;;;:::o;5721:112::-;5804:22;5820:5;5804:22;:::i;:::-;5799:3;5792:35;5721:112;;:::o;5839:214::-;5928:4;5966:2;5955:9;5951:18;5943:26;;5979:67;6043:1;6032:9;6028:17;6019:6;5979:67;:::i;:::-;5839:214;;;;:::o;6059:116::-;6129:21;6144:5;6129:21;:::i;:::-;6122:5;6119:32;6109:60;;6165:1;6162;6155:12;6109:60;6059:116;:::o;6181:133::-;6224:5;6262:6;6249:20;6240:29;;6278:30;6302:5;6278:30;:::i;:::-;6181:133;;;;:::o;6320:468::-;6385:6;6393;6442:2;6430:9;6421:7;6417:23;6413:32;6410:119;;;6448:79;;:::i;:::-;6410:119;6568:1;6593:53;6638:7;6629:6;6618:9;6614:22;6593:53;:::i;:::-;6583:63;;6539:117;6695:2;6721:50;6763:7;6754:6;6743:9;6739:22;6721:50;:::i;:::-;6711:60;;6666:115;6320:468;;;;;:::o;6794:329::-;6853:6;6902:2;6890:9;6881:7;6877:23;6873:32;6870:119;;;6908:79;;:::i;:::-;6870:119;7028:1;7053:53;7098:7;7089:6;7078:9;7074:22;7053:53;:::i;:::-;7043:63;;6999:117;6794:329;;;;:::o;7129:118::-;7216:24;7234:5;7216:24;:::i;:::-;7211:3;7204:37;7129:118;;:::o;7253:222::-;7346:4;7384:2;7373:9;7369:18;7361:26;;7397:71;7465:1;7454:9;7450:17;7441:6;7397:71;:::i;:::-;7253:222;;;;:::o;7481:117::-;7590:1;7587;7580:12;7604:117;7713:1;7710;7703:12;7727:117;7836:1;7833;7826:12;7867:568;7940:8;7950:6;8000:3;7993:4;7985:6;7981:17;7977:27;7967:122;;8008:79;;:::i;:::-;7967:122;8121:6;8108:20;8098:30;;8151:18;8143:6;8140:30;8137:117;;;8173:79;;:::i;:::-;8137:117;8287:4;8279:6;8275:17;8263:29;;8341:3;8333:4;8325:6;8321:17;8311:8;8307:32;8304:41;8301:128;;;8348:79;;:::i;:::-;8301:128;7867:568;;;;;:::o;8458:::-;8531:8;8541:6;8591:3;8584:4;8576:6;8572:17;8568:27;8558:122;;8599:79;;:::i;:::-;8558:122;8712:6;8699:20;8689:30;;8742:18;8734:6;8731:30;8728:117;;;8764:79;;:::i;:::-;8728:117;8878:4;8870:6;8866:17;8854:29;;8932:3;8924:4;8916:6;8912:17;8902:8;8898:32;8895:41;8892:128;;;8939:79;;:::i;:::-;8892:128;8458:568;;;;;:::o;9032:934::-;9154:6;9162;9170;9178;9227:2;9215:9;9206:7;9202:23;9198:32;9195:119;;;9233:79;;:::i;:::-;9195:119;9381:1;9370:9;9366:17;9353:31;9411:18;9403:6;9400:30;9397:117;;;9433:79;;:::i;:::-;9397:117;9546:80;9618:7;9609:6;9598:9;9594:22;9546:80;:::i;:::-;9528:98;;;;9324:312;9703:2;9692:9;9688:18;9675:32;9734:18;9726:6;9723:30;9720:117;;;9756:79;;:::i;:::-;9720:117;9869:80;9941:7;9932:6;9921:9;9917:22;9869:80;:::i;:::-;9851:98;;;;9646:313;9032:934;;;;;;;:::o;9972:474::-;10040:6;10048;10097:2;10085:9;10076:7;10072:23;10068:32;10065:119;;;10103:79;;:::i;:::-;10065:119;10223:1;10248:53;10293:7;10284:6;10273:9;10269:22;10248:53;:::i;:::-;10238:63;;10194:117;10350:2;10376:53;10421:7;10412:6;10401:9;10397:22;10376:53;:::i;:::-;10366:63;;10321:118;9972:474;;;;;:::o;10452:180::-;10500:77;10497:1;10490:88;10597:4;10594:1;10587:15;10621:4;10618:1;10611:15;10638:320;10682:6;10719:1;10713:4;10709:12;10699:22;;10766:1;10760:4;10756:12;10787:18;10777:81;;10843:4;10835:6;10831:17;10821:27;;10777:81;10905:2;10897:6;10894:14;10874:18;10871:38;10868:84;;10924:18;;:::i;:::-;10868:84;10689:269;10638:320;;;:::o;10964:177::-;11104:29;11100:1;11092:6;11088:14;11081:53;10964:177;:::o;11147:366::-;11289:3;11310:67;11374:2;11369:3;11310:67;:::i;:::-;11303:74;;11386:93;11475:3;11386:93;:::i;:::-;11504:2;11499:3;11495:12;11488:19;;11147:366;;;:::o;11519:419::-;11685:4;11723:2;11712:9;11708:18;11700:26;;11772:9;11766:4;11762:20;11758:1;11747:9;11743:17;11736:47;11800:131;11926:4;11800:131;:::i;:::-;11792:139;;11519:419;;;:::o;11944:171::-;12084:23;12080:1;12072:6;12068:14;12061:47;11944:171;:::o;12121:366::-;12263:3;12284:67;12348:2;12343:3;12284:67;:::i;:::-;12277:74;;12360:93;12449:3;12360:93;:::i;:::-;12478:2;12473:3;12469:12;12462:19;;12121:366;;;:::o;12493:419::-;12659:4;12697:2;12686:9;12682:18;12674:26;;12746:9;12740:4;12736:20;12732:1;12721:9;12717:17;12710:47;12774:131;12900:4;12774:131;:::i;:::-;12766:139;;12493:419;;;:::o;12918:226::-;13058:34;13054:1;13046:6;13042:14;13035:58;13127:9;13122:2;13114:6;13110:15;13103:34;12918:226;:::o;13150:366::-;13292:3;13313:67;13377:2;13372:3;13313:67;:::i;:::-;13306:74;;13389:93;13478:3;13389:93;:::i;:::-;13507:2;13502:3;13498:12;13491:19;;13150:366;;;:::o;13522:419::-;13688:4;13726:2;13715:9;13711:18;13703:26;;13775:9;13769:4;13765:20;13761:1;13750:9;13746:17;13739:47;13803:131;13929:4;13803:131;:::i;:::-;13795:139;;13522:419;;;:::o;13947:227::-;14087:34;14083:1;14075:6;14071:14;14064:58;14156:10;14151:2;14143:6;14139:15;14132:35;13947:227;:::o;14180:366::-;14322:3;14343:67;14407:2;14402:3;14343:67;:::i;:::-;14336:74;;14419:93;14508:3;14419:93;:::i;:::-;14537:2;14532:3;14528:12;14521:19;;14180:366;;;:::o;14552:419::-;14718:4;14756:2;14745:9;14741:18;14733:26;;14805:9;14799:4;14795:20;14791:1;14780:9;14776:17;14769:47;14833:131;14959:4;14833:131;:::i;:::-;14825:139;;14552:419;;;:::o;14977:85::-;15022:7;15051:5;15040:16;;14977:85;;;:::o;15068:158::-;15126:9;15159:61;15177:42;15186:32;15212:5;15186:32;:::i;:::-;15177:42;:::i;:::-;15159:61;:::i;:::-;15146:74;;15068:158;;;:::o;15232:147::-;15327:45;15366:5;15327:45;:::i;:::-;15322:3;15315:58;15232:147;;:::o;15385:807::-;15634:4;15672:3;15661:9;15657:19;15649:27;;15686:71;15754:1;15743:9;15739:17;15730:6;15686:71;:::i;:::-;15767:72;15835:2;15824:9;15820:18;15811:6;15767:72;:::i;:::-;15849:80;15925:2;15914:9;15910:18;15901:6;15849:80;:::i;:::-;15939;16015:2;16004:9;16000:18;15991:6;15939:80;:::i;:::-;16029:73;16097:3;16086:9;16082:19;16073:6;16029:73;:::i;:::-;16112;16180:3;16169:9;16165:19;16156:6;16112:73;:::i;:::-;15385:807;;;;;;;;;:::o;16198:143::-;16255:5;16286:6;16280:13;16271:22;;16302:33;16329:5;16302:33;:::i;:::-;16198:143;;;;:::o;16347:663::-;16435:6;16443;16451;16500:2;16488:9;16479:7;16475:23;16471:32;16468:119;;;16506:79;;:::i;:::-;16468:119;16626:1;16651:64;16707:7;16698:6;16687:9;16683:22;16651:64;:::i;:::-;16641:74;;16597:128;16764:2;16790:64;16846:7;16837:6;16826:9;16822:22;16790:64;:::i;:::-;16780:74;;16735:129;16903:2;16929:64;16985:7;16976:6;16965:9;16961:22;16929:64;:::i;:::-;16919:74;;16874:129;16347:663;;;;;:::o;17016:143::-;17073:5;17104:6;17098:13;17089:22;;17120:33;17147:5;17120:33;:::i;:::-;17016:143;;;;:::o;17165:351::-;17235:6;17284:2;17272:9;17263:7;17259:23;17255:32;17252:119;;;17290:79;;:::i;:::-;17252:119;17410:1;17435:64;17491:7;17482:6;17471:9;17467:22;17435:64;:::i;:::-;17425:74;;17381:128;17165:351;;;;:::o;17522:332::-;17643:4;17681:2;17670:9;17666:18;17658:26;;17694:71;17762:1;17751:9;17747:17;17738:6;17694:71;:::i;:::-;17775:72;17843:2;17832:9;17828:18;17819:6;17775:72;:::i;:::-;17522:332;;;;;:::o;17860:442::-;18009:4;18047:2;18036:9;18032:18;18024:26;;18060:71;18128:1;18117:9;18113:17;18104:6;18060:71;:::i;:::-;18141:72;18209:2;18198:9;18194:18;18185:6;18141:72;:::i;:::-;18223;18291:2;18280:9;18276:18;18267:6;18223:72;:::i;:::-;17860:442;;;;;;:::o;18308:168::-;18448:20;18444:1;18436:6;18432:14;18425:44;18308:168;:::o;18482:366::-;18624:3;18645:67;18709:2;18704:3;18645:67;:::i;:::-;18638:74;;18721:93;18810:3;18721:93;:::i;:::-;18839:2;18834:3;18830:12;18823:19;;18482:366;;;:::o;18854:419::-;19020:4;19058:2;19047:9;19043:18;19035:26;;19107:9;19101:4;19097:20;19093:1;19082:9;19078:17;19071:47;19135:131;19261:4;19135:131;:::i;:::-;19127:139;;18854:419;;;:::o;19279:147::-;19380:11;19417:3;19402:18;;19279:147;;;;:::o;19432:114::-;;:::o;19552:398::-;19711:3;19732:83;19813:1;19808:3;19732:83;:::i;:::-;19725:90;;19824:93;19913:3;19824:93;:::i;:::-;19942:1;19937:3;19933:11;19926:18;;19552:398;;;:::o;19956:379::-;20140:3;20162:147;20305:3;20162:147;:::i;:::-;20155:154;;20326:3;20319:10;;19956:379;;;:::o;20341:166::-;20481:18;20477:1;20469:6;20465:14;20458:42;20341:166;:::o;20513:366::-;20655:3;20676:67;20740:2;20735:3;20676:67;:::i;:::-;20669:74;;20752:93;20841:3;20752:93;:::i;:::-;20870:2;20865:3;20861:12;20854:19;;20513:366;;;:::o;20885:419::-;21051:4;21089:2;21078:9;21074:18;21066:26;;21138:9;21132:4;21128:20;21124:1;21113:9;21109:17;21102:47;21166:131;21292:4;21166:131;:::i;:::-;21158:139;;20885:419;;;:::o;21310:173::-;21450:25;21446:1;21438:6;21434:14;21427:49;21310:173;:::o;21489:366::-;21631:3;21652:67;21716:2;21711:3;21652:67;:::i;:::-;21645:74;;21728:93;21817:3;21728:93;:::i;:::-;21846:2;21841:3;21837:12;21830:19;;21489:366;;;:::o;21861:419::-;22027:4;22065:2;22054:9;22050:18;22042:26;;22114:9;22108:4;22104:20;22100:1;22089:9;22085:17;22078:47;22142:131;22268:4;22142:131;:::i;:::-;22134:139;;21861:419;;;:::o;22286:175::-;22426:27;22422:1;22414:6;22410:14;22403:51;22286:175;:::o;22467:366::-;22609:3;22630:67;22694:2;22689:3;22630:67;:::i;:::-;22623:74;;22706:93;22795:3;22706:93;:::i;:::-;22824:2;22819:3;22815:12;22808:19;;22467:366;;;:::o;22839:419::-;23005:4;23043:2;23032:9;23028:18;23020:26;;23092:9;23086:4;23082:20;23078:1;23067:9;23063:17;23056:47;23120:131;23246:4;23120:131;:::i;:::-;23112:139;;22839:419;;;:::o;23264:170::-;23404:22;23400:1;23392:6;23388:14;23381:46;23264:170;:::o;23440:366::-;23582:3;23603:67;23667:2;23662:3;23603:67;:::i;:::-;23596:74;;23679:93;23768:3;23679:93;:::i;:::-;23797:2;23792:3;23788:12;23781:19;;23440:366;;;:::o;23812:419::-;23978:4;24016:2;24005:9;24001:18;23993:26;;24065:9;24059:4;24055:20;24051:1;24040:9;24036:17;24029:47;24093:131;24219:4;24093:131;:::i;:::-;24085:139;;23812:419;;;:::o;24237:180::-;24285:77;24282:1;24275:88;24382:4;24379:1;24372:15;24406:4;24403:1;24396:15;24423:180;24471:77;24468:1;24461:88;24568:4;24565:1;24558:15;24592:4;24589:1;24582:15;24609:191;24649:3;24668:20;24686:1;24668:20;:::i;:::-;24663:25;;24702:20;24720:1;24702:20;:::i;:::-;24697:25;;24745:1;24742;24738:9;24731:16;;24766:3;24763:1;24760:10;24757:36;;;24773:18;;:::i;:::-;24757:36;24609:191;;;;:::o;24806:171::-;24946:23;24942:1;24934:6;24930:14;24923:47;24806:171;:::o;24983:366::-;25125:3;25146:67;25210:2;25205:3;25146:67;:::i;:::-;25139:74;;25222:93;25311:3;25222:93;:::i;:::-;25340:2;25335:3;25331:12;25324:19;;24983:366;;;:::o;25355:419::-;25521:4;25559:2;25548:9;25544:18;25536:26;;25608:9;25602:4;25598:20;25594:1;25583:9;25579:17;25572:47;25636:131;25762:4;25636:131;:::i;:::-;25628:139;;25355:419;;;:::o;25780:332::-;25901:4;25939:2;25928:9;25924:18;25916:26;;25952:71;26020:1;26009:9;26005:17;25996:6;25952:71;:::i;:::-;26033:72;26101:2;26090:9;26086:18;26077:6;26033:72;:::i;:::-;25780:332;;;;;:::o;26118:351::-;26188:6;26237:2;26225:9;26216:7;26212:23;26208:32;26205:119;;;26243:79;;:::i;:::-;26205:119;26363:1;26388:64;26444:7;26435:6;26424:9;26420:22;26388:64;:::i;:::-;26378:74;;26334:128;26118:351;;;;:::o;26475:174::-;26615:26;26611:1;26603:6;26599:14;26592:50;26475:174;:::o;26655:366::-;26797:3;26818:67;26882:2;26877:3;26818:67;:::i;:::-;26811:74;;26894:93;26983:3;26894:93;:::i;:::-;27012:2;27007:3;27003:12;26996:19;;26655:366;;;:::o;27027:419::-;27193:4;27231:2;27220:9;27216:18;27208:26;;27280:9;27274:4;27270:20;27266:1;27255:9;27251:17;27244:47;27308:131;27434:4;27308:131;:::i;:::-;27300:139;;27027:419;;;:::o;27452:332::-;27573:4;27611:2;27600:9;27596:18;27588:26;;27624:71;27692:1;27681:9;27677:17;27668:6;27624:71;:::i;:::-;27705:72;27773:2;27762:9;27758:18;27749:6;27705:72;:::i;:::-;27452:332;;;;;:::o;27790:137::-;27844:5;27875:6;27869:13;27860:22;;27891:30;27915:5;27891:30;:::i;:::-;27790:137;;;;:::o;27933:345::-;28000:6;28049:2;28037:9;28028:7;28024:23;28020:32;28017:119;;;28055:79;;:::i;:::-;28017:119;28175:1;28200:61;28253:7;28244:6;28233:9;28229:22;28200:61;:::i;:::-;28190:71;;28146:125;27933:345;;;;:::o;28284:442::-;28433:4;28471:2;28460:9;28456:18;28448:26;;28484:71;28552:1;28541:9;28537:17;28528:6;28484:71;:::i;:::-;28565:72;28633:2;28622:9;28618:18;28609:6;28565:72;:::i;:::-;28647;28715:2;28704:9;28700:18;28691:6;28647:72;:::i;:::-;28284:442;;;;;;:::o
Swarm Source
ipfs://38fb86a8a5032b2ed2c0d4550e4e02c76f8aff274285238fc5860aaa999f8206
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.