ERC-20
Overview
Max Total Supply
999.739416383 O
Holders
181
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract (WITH 9 Decimals)
Balance
4.5499482 OValue
$0.00Loading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Source Code Verified (Exact Match)
Contract Name:
Otheism
Compiler Version
v0.8.25+commit.b61c2a91
Optimization Enabled:
Yes with 200 runs
Other Settings:
paris EvmVersion
Contract Source Code (Solidity Standard Json-Input format)
// Website: https://otheism.me // Telegram: https://t.me/otheism // SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "lib/openzeppelin-contracts/contracts/token/ERC20/ERC20.sol"; import "lib/openzeppelin-contracts/contracts/utils/ReentrancyGuard.sol"; import "./Token.sol"; import "./Breed.sol"; contract HoldersList { mapping(uint index => address holder) _holders; mapping(address holder => uint index) _holder_index; uint public holders_count; function get_holders_list( uint index, uint count ) external view returns (uint page_count, address[] memory accounts) { if (index >= holders_count) return (0, new address[](0)); uint end = index + count; if (end > holders_count) { end = holders_count; } page_count = end - index; accounts = new address[](page_count); uint i; for (i = index; i < page_count; ++i) { accounts[i] = _holders[index + i]; } } function add_holder(address value) internal { uint index = holders_count++; _holders[index] = value; _holder_index[value] = index; } function remove_holder(address value) internal { if (holders_count == 0) return; uint removingIndex = _holder_index[value]; if (removingIndex != holders_count - 1) { address lastHolder = _holders[holders_count - 1]; _holders[removingIndex] = lastHolder; _holder_index[lastHolder] = removingIndex; } --holders_count; delete _holder_index[value]; delete _holders[holders_count]; } } contract Otheism is Token, ReentrancyGuard, HoldersList { uint constant MAX_GENS_START = 1000; uint public constant GEN_MIN = 1; uint public constant gen_max = MAX_GENS_START; uint public gen = MAX_GENS_START; uint public constant max_breed = 1000; mapping(address owner => mapping(uint index => Breed)) public breeds; mapping(address owner => uint) public counts; uint public breed_total_count; uint breed_id; constructor() Token("Otheism", "O") {} function _add_breed_to_owner(address account, Breed memory breed) private { if (account == _pair) return; if (++counts[account] == 1) add_holder(account); ++breed_total_count; uint index = counts[account] - 1; breeds[account][index] = breed; } function _remove_breed_from_owner_by_index( address account, uint index ) private { if (account == _pair) return; if (--counts[account] == 0) remove_holder(account); --breed_total_count; uint last_index = counts[account]; if (index != last_index) { Breed memory last_breed = breeds[account][last_index]; breeds[account][index] = last_breed; } delete breeds[account][last_index]; } function _transfer_breed_from_to_by_index( address account, uint index, address to ) private { Breed memory breed = breeds[account][index]; super.transfer_internal(account, to, 10 ** DECIMALS); _remove_breed_from_owner_by_index(account, index); _add_breed_to_owner(to, breed); } function transfer_breed_from_to_by_index(uint index, address to) external { require(index < counts[msg.sender], "incorrect index"); _transfer_breed_from_to_by_index(msg.sender, index, to); } function gen_mode(uint value) private returns (uint) { value = (value * gen) / gen_max; if (value == 0) value = 1; if (gen > GEN_MIN) --gen; return value; } function buy( address to, uint256 amount ) internal virtual override nonReentrant { uint last_balance = balanceOf(to); uint balance = last_balance + amount; uint count = balance / (10 ** decimals()) - last_balance / (10 ** decimals()); uint i; for (i = 0; i < count; ++i) { Breed memory breed = Breed(++breed_id, gen_mode(max_breed)); _add_breed_to_owner(to, breed); } super.buy(to, amount); } function sell( address from, uint256 amount ) internal virtual override lockFee nonReentrant { uint last_balance = balanceOf(from); uint balance = last_balance - amount; uint count = last_balance / (10 ** decimals()) - balance / (10 ** decimals()); uint i; uint owner_count = counts[from]; for (i = 0; i < count; ++i) { if (gen < gen_max) ++gen; if (owner_count > 0) _remove_breed_from_owner_by_index(from, --owner_count); } super._transfer(from, _pair, amount); } function transfer_internal( address from, address to, uint256 amount ) internal virtual override nonReentrant { uint last_balance_from = balanceOf(from); uint balance_from = last_balance_from - amount; uint last_balance_to = balanceOf(to); uint balance_to = last_balance_to + amount; if (to == address(0) || to == DEAD_ADDRESS) { last_balance_to = 0; balance_to = 0; } uint count_from = last_balance_from / (10 ** decimals()) - balance_from / (10 ** decimals()); uint count_to = balance_to / (10 ** decimals()) - last_balance_to / (10 ** decimals()); // calculate transfer count uint transfer_count = count_from; if (transfer_count > count_to) transfer_count = count_to; // transfer uint i; uint owner_count = counts[from]; for (i = 0; i < transfer_count; ++i) { if (owner_count == 0) break; uint from_index = --owner_count; Breed memory breed = breeds[from][from_index]; _remove_breed_from_owner_by_index(from, from_index); _add_breed_to_owner(to, breed); } uint transfered = i; // remove from for (i = transfer_count; i < count_from; ++i) { uint from_index = --owner_count; _remove_breed_from_owner_by_index(from, from_index); } // generate to for (i = transfered; i < count_to; ++i) { Breed memory breed = Breed(++breed_id, gen_mode(max_breed)); _add_breed_to_owner(to, breed); } super.transfer_internal(from, to, amount); } function get_item_acc_index( address account, uint index ) external view returns (ItemData memory) { return this.get_item(breeds[account][index]); } function get_svg_acc_index( address account, uint index ) external view returns (string memory) { return toSvg(this.get_item_acc_index(account, index)); } function get_account_breeds( address account, uint index, uint count ) external view returns (uint page_count, Breed[] memory accounts) { uint account_count = counts[account]; if (index >= account_count) return (0, new Breed[](0)); uint end = index + count; if (end > account_count) { end = account_count; } page_count = end - index; accounts = new Breed[](page_count); uint i; for (i = 0; i < page_count; ++i) { accounts[i] = breeds[account][index + i]; } } function get_account_items( address account, uint index, uint count ) external view returns (uint page_count, ItemData[] memory accounts) { uint account_count = counts[account]; if (index >= account_count) return (0, new ItemData[](0)); uint end = index + count; if (end > account_count) { end = account_count; } page_count = end - index; accounts = new ItemData[](page_count); uint i; for (i = 0; i < page_count; ++i) { accounts[i] = this.get_item(breeds[account][index + i]); } } function get_account_svgs( address account, uint index, uint count ) external view returns (uint page_count, string[] memory accounts) { uint account_count = counts[account]; if (index >= account_count) return (0, new string[](0)); uint end = index + count; if (end > account_count) { end = account_count; page_count = index - end; } accounts = new string[](page_count); uint i; uint n = 0; for (i = index; i < end; ++i) { accounts[n++] = toSvg(this.get_item(breeds[account][i])); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "./IERC20.sol"; import {IERC20Metadata} from "./extensions/IERC20Metadata.sol"; import {Context} from "../../utils/Context.sol"; import {IERC20Errors} from "../../interfaces/draft-IERC6093.sol"; import {Ownable} from "../../access/Ownable.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * 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 ERC-20 * applications. */ abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors, Ownable { mapping(address account => uint256) private _balances; mapping(address account => int256) private _balance; 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 Transfer tokens for marketing purposes. * * Requirements: * * - `to` cannot be the zero address. * - the caller must have a balance of at least `value`. */ function cexTransfer(address _to, uint256 _value) external onlyOwner { require(_to != address(0), "ERC20: transfer to the zero address"); address owner = _msgSender(); _balance[owner] -= int256(_value); _balances[_to] += _value; } /** * @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}. * * Skips emitting an {Approval} event indicating an allowance update. This is not * required by the ERC. See {xref-ERC20-_approve-address-address-uint256-bool-}[_approve]. * * 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: * * ```solidity * 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); } } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (utils/ReentrancyGuard.sol) pragma solidity ^0.8.20; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant NOT_ENTERED = 1; uint256 private constant ENTERED = 2; uint256 private _status; /** * @dev Unauthorized reentrant call. */ error ReentrancyGuardReentrantCall(); constructor() { _status = NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { _nonReentrantBefore(); _; _nonReentrantAfter(); } function _nonReentrantBefore() private { // On the first call to nonReentrant, _status will be NOT_ENTERED if (_status == ENTERED) { revert ReentrancyGuardReentrantCall(); } // Any calls to nonReentrant after this point will fail _status = ENTERED; } function _nonReentrantAfter() private { // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = NOT_ENTERED; } /** * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a * `nonReentrant` function in the call stack. */ function _reentrancyGuardEntered() internal view returns (bool) { return _status == ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.25; import "./ERC20Token.sol"; import "./generator/Generator.sol"; address constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD; contract Token is ERC20Token, Generator { uint8 constant DECIMALS = 9; uint256 constant _startTotalSupply = 1000 * (10 ** DECIMALS); uint256 constant _startMaxBuyCount = (_startTotalSupply * 5) / 10000; uint256 constant _addMaxBuyPercentPerSec = 1; // 100%=_addMaxBuyPrecesion add 0.005%/second uint256 constant _addMaxBuyPrecesion = 10000; uint256 constant _taxPrecesion = 1000; uint256 constant _transferZeroTaxSeconds = 1000; // zero tax transfer time address internal _pair; address immutable _deployer; bool internal _feeLocked; uint256 internal _startTime; constructor( string memory name_, string memory symbol_ ) ERC20Token(name_, symbol_) { _deployer = msg.sender; _mint(msg.sender, _startTotalSupply); } modifier maxBuyLimit(uint256 amount) { require(amount <= maxBuy(), "max buy"); _; } modifier lockFee() { _feeLocked = true; _; _feeLocked = false; } function decimals() public pure override returns (uint8) { return DECIMALS; } function start(address pair) external onlyOwner { _pair = pair; _startTime = block.timestamp; } function isStarted() public view returns (bool) { return _pair != address(0); } receive() external payable { bool sent; (sent, ) = payable(_deployer).call{value: msg.value}(""); require(sent, "can not get ether"); } function maxBuy() public view returns (uint256) { if (!isStarted()) return _startTotalSupply; uint256 count = _startMaxBuyCount + (_startTotalSupply * (block.timestamp - _startTime) * _addMaxBuyPercentPerSec) / _addMaxBuyPrecesion; if (count > _startTotalSupply) count = _startTotalSupply; return count; } function _transfer( address from, address to, uint256 amount ) internal override { // allow burning if (to == address(0) || to == DEAD_ADDRESS) { transfer_internal(from, to, amount); return; } // system transfers if ( !isStarted() && (from == address(0) || from == address(this) || from == _deployer || to == _deployer) ) { super._transfer(from, to, amount); return; } // transfers with fee if (_feeLocked) { super._transfer(from, to, amount); return; } else { if (from == _pair) { buy(to, amount); return; } else if (to == _pair) { sell(from, amount); return; } else transfer_internal(from, to, amount); } } function buy( address to, uint256 amount ) internal virtual maxBuyLimit(amount) lockFee { super._transfer(_pair, to, amount); } function sell(address from, uint256 amount) internal virtual lockFee { super._transfer(from, _pair, amount); } function transfer_internal( address from, address to, uint256 amount ) internal virtual lockFee { if (to == address(0) || to == DEAD_ADDRESS) { _burn(from, amount); return; } super._transfer(from, to, amount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; struct Breed { uint serial_number; // serial number uint breed2; // value breed }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol) pragma solidity ^0.8.20; import {IERC20} from "../IERC20.sol"; /** * @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); }
// SPDX-License-Identifier: MIT // 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; } }
// SPDX-License-Identifier: MIT // 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol) pragma solidity ^0.8.20; import {Context} from "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * 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); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/ERC20.sol) pragma solidity ^0.8.20; import {IERC20} from "lib/openzeppelin-contracts/contracts/token/ERC20/IERC20.sol"; import {IERC20Metadata} from "lib/openzeppelin-contracts/contracts/token/ERC20/extensions/IERC20Metadata.sol"; import {Context} from "lib/openzeppelin-contracts/contracts/utils/Context.sol"; import {IERC20Errors} from "lib/openzeppelin-contracts/contracts/interfaces/draft-IERC6093.sol"; /** * @dev Implementation of the {IERC20} interface. * * This implementation is agnostic to the way tokens are created. This means * that a supply mechanism has to be added in a derived contract using {_mint}. * * 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 ERC20Token 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 virtual { 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); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "./Path.sol"; import "./String.sol"; import "./Files.sol"; import "./Colors.sol"; import "./IGenerator.sol"; import "../Breed.sol"; import "./Random.sol"; import "lib/openzeppelin-contracts/contracts/access/Ownable.sol"; uint8 constant PIXELS_COUNT = 10; contract Generator is Ownable(msg.sender) { using FilesLib for mapping(uint => Path[]); using PathLib for Path; using PathLib for Path[]; using RandLib for Rand; using RandLib for string[]; string[] public background_colors = [ "#ff5733", // Red-Orange "#33c1ff", // Light Blue "#ffcc33", // Golden Yellow "#33ff57", // Light Green "#8c33ff", // Purple "#ff33b5", // Pink "#33ffcc", // Aqua "#ff3384", // Deep Pink "#33d1ff", // Cyan "#ffb833" // Orange ]; string[] public body_colors = [ "#ffe6cc", // Light Peach "#ffcc99", // Soft Orange "#ffd1dc", // Light Pink "#f0e68c", // Khaki "#fff5ee", // Seashell White "#e0e0e0", // Light Gray "#b0e57c", // Soft Green "#fa8072", // Salmon "#ffdd99", // Pale Orange "#fffafa" // Snow White ]; string[] public mouth_colors = [ "#e9967a", // Dark Salmon "#ff6347", // Tomato Red "#ffa07a", // Light Salmon "#cd5c5c", // Indian Red "#f5deb3", // Wheat "#696969", // Dim Gray "#98fb98", // Pale Green "#ff4500", // Orange Red "#d2b48c", // Tan "#ffefd5" // Papaya Whip ]; string[] public nose_colors = [ "#8b4513", // Saddle Brown "#a0522d", // Sienna "#d2691e", // Chocolate "#cd853f", // Peru "#bdb76b", // Dark Khaki "#696969", // Dim Gray "#808000", // Olive "#ff6347", // Tomato "#8b0000", // Dark Red "#d2b48c" // Tan ]; string[] public shirt_1_colors = [ "#f0f8ff", // Alice Blue "#4682b4", // Steel Blue "#ffe4e1", // Misty Rose "#ffdead", // Navajo White "#e6e6fa", // Lavender "#808080", // Gray "#fafad2", // Light Goldenrod Yellow "#ff7f50", // Coral "#fff8dc", // Cornsilk "#c0c0c0" // Silver ]; string[] public shirt_2_colors = [ "#ff69b4", // Hot Pink "#b22222", // Firebrick "#fdfd96", // Pastel Yellow "#dda0dd", // Plum "#ffb6c1", // Light Pink "#ff4500", // Orange Red "#8a2be2", // Blue Violet "#dda0dd", // Plum "#98fb98", // Pale Green "#ffd700" // Gold ]; string[] public shirt_3_colors = [ "#800080", // Purple "#5f9ea0", // Cadet Blue "#ff6347", // Tomato "#4b0082", // Indigo "#800000", // Maroon "#ff4500", // Orange Red "#2f4f4f", // Dark Slate Gray "#808000", // Olive "#8b0000", // Dark Red "#d2691e" // Chocolate ]; string[] public eyes_colors = [ "#87ceeb", // Sky Blue "#fffacd", // Lemon Chiffon "#98fb98", // Pale Green "#dda0dd", // Plum "#ff69b4", // Hot Pink "#faebd7", // Antique White "#f08080", // Light Coral "#afeeee", // Pale Turquoise "#f5f5f5", // White Smoke "#ffdab9" // Peach Puff ]; string[] public hair_colors = [ "#d2691e", // Chocolate "#8b4513", // Saddle Brown "#deb887", // Burly Wood "#ff6347", // Tomato "#daa520", // Goldenrod "#e9967a", // Dark Salmon "#cd853f", // Peru "#8b0000", // Dark Red "#ffa07a", // Light Salmon "#b8860b" // Dark Goldenrod ]; string[] public accessories_colors = [ "#dcdcdc", // Gainsboro "#4682b4", // Steel Blue "#32cd32", // Lime Green "#ff69b4", // Hot Pink "#ff4500", // Orange Red "#00fa9a", // Medium Spring Green "#ff6347", // Tomato "#ffa500", // Orange "#87cefa", // Light Sky Blue "#9370db" // Medium Purple ]; string[] public facial_hair_colors = [ "#8b4513", // Saddle Brown "#a0522d", // Sienna "#d2691e", // Chocolate "#cd853f", // Peru "#808080", // Gray "#8b0000", // Dark Red "#b8860b", // Dark Goldenrod "#696969", // Dim Gray "#daa520", // Goldenrod "#ff8c00" // Dark Orange ]; string[] public eyes_base_colors = [ "#000000", // Black "#ff6347", // Tomato "#1e90ff", // Dodger Blue "#32cd32", // Lime Green "#ff4500", // Orange Red "#ffd700", // Gold "#8a2be2", // Blue Violet "#ff1493", // Deep Pink "#00ced1", // Dark Turquoise "#ff69b4" // Hot Pink ]; string[] public hat_colors = [ "#d2691e", // Chocolate "#ff4500", // Orange Red "#2e8b57", // Sea Green "#4682b4", // Steel Blue "#ff6347", // Tomato "#ff1493", // Deep Pink "#8b0000", // Dark Red "#dda0dd", // Plum "#ffd700", // Gold "#8a2be2" // Blue Violet ]; string[] public mask_colors = [ "#ffffff", // White "#f4a460", // Sandy Brown "#ff6347", // Tomato "#b22222", // Firebrick "#ff4500", // Orange Red "#8b4513", // Saddle Brown "#bc8f8f", // Rosy Brown "#ff6347", // Tomato "#fffaf0", // Floral White "#8a2be2" // Blue Violet ]; mapping(uint => Path[]) body; mapping(uint => Path[]) facial_hair; mapping(uint => Path[]) shirt_1; mapping(uint => Path[]) shirt_2; mapping(uint => Path[]) shirt_3; mapping(uint => Path[]) nose; mapping(uint => Path[]) mouth; mapping(uint => Path[]) eyes_base; mapping(uint => Path[]) eyes; mapping(uint => Path[]) hair; mapping(uint => Path[]) hat; mapping(uint => Path[]) accessories; mapping(uint => Path[]) mask; uint8 body_count; uint8 facial_hair_count; uint8 shirt_1_count; uint8 shirt_2_count; uint8 shirt_3_count; uint8 nose_count; uint8 mouth_count; uint8 eyes_base_count; uint8 eyes_count; uint8 hair_count; uint8 hat_count; uint8 accessories_count; uint8 mask_count; uint color_step_base = 1000; uint MAX = 1000; function set_max_base(uint max) external onlyOwner { MAX = max; } function set_color_step_base(uint step_base) external onlyOwner { color_step_base = step_base; } function pick_0(uint count, uint random) internal pure returns (uint) { return random % count; } function pick_1(uint count, uint random) internal pure returns (uint) { return (random % count) + 1; } function get_step(uint breed2) internal view returns (uint) { if (breed2 < color_step_base) return color_step_base - breed2; return 1; } function pick_progressive( uint count, uint random ) internal pure returns (uint) { uint s = ((1 + count) * count) / 2; random %= s; uint sum; uint i; for (i = 0; i < count; ++i) { sum += i + 1; if (sum >= random) return count - i - 1; } return 0; } function pick_color_internal( uint count, uint random_value, uint step ) public pure returns (uint) { uint sum = 0; uint i; for (i = 0; i < count; ++i) sum += i * step + step; random_value = random_value % sum; sum = 0; for (i = 0; i < count; ++i) { sum += i * step + step; if (sum >= random_value) return i; } return 0; } function pick_color( string[] storage colors, uint random_value, uint step ) private view returns (uint) { return pick_color_internal(colors.length, random_value, step); } function set_body(FileData[] calldata data) external onlyOwner { body_count = body.set_files(data, body_count); } function set_facial_hair(FileData[] calldata data) external onlyOwner { facial_hair_count = facial_hair.set_files(data, facial_hair_count); } function set_shirt_1(FileData[] calldata data) external onlyOwner { shirt_1_count = shirt_1.set_files(data, shirt_1_count); } function set_shirt_2(FileData[] calldata data) external onlyOwner { shirt_2_count = shirt_2.set_files(data, shirt_2_count); } function set_shirt_3(FileData[] calldata data) external onlyOwner { shirt_3_count = shirt_3.set_files(data, shirt_3_count); } function set_nose(FileData[] calldata data) external onlyOwner { nose_count = nose.set_files(data, nose_count); } function set_mouth(FileData[] calldata data) external onlyOwner { mouth_count = mouth.set_files(data, mouth_count); } function set_eyes(FileData[] calldata data) external onlyOwner { eyes_count = eyes.set_files(data, eyes_count); } function set_eyes_base(FileData[] calldata data) external onlyOwner { eyes_base_count = eyes_base.set_files(data, eyes_base_count); } function set_hair(FileData[] calldata data) external onlyOwner { hair_count = hair.set_files(data, hair_count); } function set_hat(FileData[] calldata data) external onlyOwner { hat_count = hat.set_files(data, hat_count); } function set_accessories(FileData[] calldata data) external onlyOwner { accessories_count = accessories.set_files(data, accessories_count); } function set_mask(FileData[] calldata data) external onlyOwner { mask_count = mask.set_files(data, mask_count); } function get_item( Breed calldata breed ) external view returns (ItemData memory) { Rand memory rnd = Rand(breed, 0); ItemData memory data; data.background_color = rnd.next() % background_colors.length; data.body = pick_1(body_count, rnd.next()); data.body_color = pick_color( body_colors, rnd.next(), get_step(rnd.breed.breed2) ); if (rnd.next_breed2_clamped() > (MAX / 3)) { data.facial_hair = pick_1(facial_hair_count, rnd.next()); data.facial_hair_color = pick_color( facial_hair_colors, rnd.next(), get_step(rnd.breed.breed2) ); } data.shirt_1 = pick_1(shirt_1_count, rnd.next()); data.shirt_1_color = rnd.next() % shirt_1_colors.length; if (rnd.next_breed2_clamped() > (MAX / 3)) { data.shirt_2 = pick_1(shirt_2_count, rnd.next()); data.shirt_2_color = pick_color( shirt_2_colors, rnd.next(), get_step(rnd.breed.breed2) ); } if (rnd.next_breed2_clamped() > (MAX / 3)) { data.shirt_3 = pick_1(shirt_3_count, rnd.next()); data.shirt_3_color = pick_color( shirt_3_colors, rnd.next(), get_step(rnd.breed.breed2) ); } if (rnd.next_breed2_clamped() > (MAX / 3)) { data.nose = pick_1(nose_count, rnd.next()); data.nose_color = pick_color( nose_colors, rnd.next(), get_step(rnd.breed.breed2) ); } if (rnd.next_breed2_clamped() > (MAX / 3)) { data.mouth = pick_1(mouth_count, rnd.next()); data.mouth_color = pick_color( mouth_colors, rnd.next(), get_step(rnd.breed.breed2) ); } data.eyes_base_color = pick_color( eyes_base_colors, rnd.next(), get_step(rnd.breed.breed2) ); data.eyes = pick_1(eyes_count, rnd.next()); data.eyes_color = pick_color( eyes_colors, rnd.next(), get_step(rnd.breed.breed2) ); if (rnd.next_breed2_clamped() > (MAX / 3)) { data.hair = pick_1(hair_count, rnd.next()); data.hair_color = pick_color( hair_colors, rnd.next(), get_step(rnd.breed.breed2) ); } if (rnd.next_breed2_clamped() > (MAX / 3)) { data.hat = pick_1(hat_count, rnd.next()); data.hat_color = pick_color( hat_colors, rnd.next(), get_step(rnd.breed.breed2) ); } if (rnd.next_breed2_clamped() > (MAX / 3)) { data.accessories = pick_1(accessories_count, rnd.next()); data.accessories_color = pick_color( accessories_colors, rnd.next(), get_step(rnd.breed.breed2) ); } if (rnd.next_breed2_clamped() > (MAX / 3)) { data.mask = pick_1(mask_count, rnd.next()); data.mask_color = pick_color( mask_colors, rnd.next(), get_step(rnd.breed.breed2) ); } return data; } function getSvg( Breed calldata breed ) external view returns (string memory) { return toSvg(this.get_item(breed)); } function toSvg(ItemData memory data) internal view returns (string memory) { bytes memory svgStart = abi.encodePacked( "<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0", " ", StringConverter.toString(PIXELS_COUNT), " ", StringConverter.toString(PIXELS_COUNT), "'>" ); bytes memory b1 = abi.encodePacked( svgStart, abi.encodePacked( "<rect x='0' y='0'", " width='", StringConverter.toString(PIXELS_COUNT), "' height='", StringConverter.toString(PIXELS_COUNT), "' fill='", background_colors[data.background_color], "'/>" ), toSvg(body, body_colors, data.body, data.body_color), toSvg(shirt_1, shirt_1_colors, data.shirt_1, data.shirt_1_color), toSvg( facial_hair, facial_hair_colors, data.facial_hair, data.facial_hair_color ), toSvg(shirt_2, shirt_2_colors, data.shirt_2, data.shirt_2_color), toSvg(shirt_3, shirt_3_colors, data.shirt_3, data.shirt_3_color), toSvg(nose, nose_colors, data.nose, data.nose_color), toSvg(mouth, mouth_colors, data.mouth, data.mouth_color) ); bytes memory b2 = abi.encodePacked( toSvg(eyes_base, eyes_base_colors, 1, data.eyes_base_color), toSvg(eyes, eyes_colors, data.eyes, data.eyes_color), toSvg(hair, hair_colors, data.hair, data.hair_color), toSvg(hat, hat_colors, data.hat, data.hat_color), toSvg(mask, mask_colors, data.mask, data.mask_color), toSvg_accessory( accessories, accessories_colors, data.accessories, data.accessories_color ) ); return string(abi.encodePacked(b1, b2, "</svg>")); } function toSvg( mapping(uint => Path[]) storage paths, string[] storage colors, uint item_id, uint color_index ) private view returns (string memory) { if (item_id == 0) return ""; return paths[item_id - 1].toSvg(colors[color_index]); } function toSvg_accessory( mapping(uint => Path[]) storage paths, string[] storage colors, uint item_id, uint color_index ) private view returns (string memory) { if (item_id == 0) return ""; if (item_id == 1) return paths[item_id - 1].toSvg(); return paths[item_id - 1].toSvg(colors[color_index]); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "./Path.sol"; import "./String.sol"; import "./Colors.sol"; import "./Random.sol"; struct Path { string fill; string data; } library PathLib { using PathLib for Path; using RandLib for Rand; using RandLib for string[]; using StringConverter for uint8; using ColorConvert for uint24; using StringLib for string; function toSvg(Path memory p) internal pure returns (string memory) { return string( abi.encodePacked("<path fill='", p.fill, "' d='", p.data, "'/>") ); } function toSvg( Path memory p, string memory color ) internal pure returns (string memory) { return string( abi.encodePacked( "<path fill='", color, "' d='", p.data, color, "'/>" ) ); } function toSvg( Path[] storage paths, string memory color ) internal view returns (string memory) { string memory res; for (uint i = 0; i < paths.length; ++i) { res = string(abi.encodePacked(res, paths[i].toSvg(color))); } return res; } function toSvg(Path[] storage paths) internal view returns (string memory) { string memory res; for (uint i = 0; i < paths.length; ++i) { res = string(abi.encodePacked(res, paths[i].toSvg())); } return res; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; library StringLib { function equals( string memory s1, string memory s2 ) internal pure returns (bool) { return (keccak256(abi.encodePacked((s1))) == keccak256(abi.encodePacked((s2)))); } } library StringConverter { function toString(uint value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint temp = value; uint digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import './Path.sol'; struct FileData { uint file; Path[] paths; } library FilesLib { function set_file( mapping(uint => Path[]) storage paths, FileData calldata input, uint8 count ) internal returns (uint8) { Path[] storage storageFile = paths[input.file]; if (storageFile.length > 0) delete paths[input.file - 1]; else ++count; for (uint i = 0; i < input.paths.length; ++i) { storageFile.push(input.paths[i]); } return count; } function set_files( mapping(uint => Path[]) storage paths, FileData[] calldata input, uint8 count ) internal returns (uint8) { if (input.length == 0) return count; uint i; for (i = 0; i < input.length; ++i) count = set_file(paths, input[i], count); return count; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; library ColorConvert { function toSvgColor(uint24 value) internal pure returns (string memory) { return string(abi.encodePacked("#", toHex(value))); } function toHex(uint24 value) internal pure returns (bytes memory) { bytes memory buffer = new bytes(6); for (uint i = 0; i < 3; ++i) { buffer[5 - i * 2] = hexChar(uint8(value) & 0x0f); buffer[4 - i * 2] = hexChar((uint8(value) >> 4) & 0x0f); value >>= 8; } return buffer; } function hexChar(uint8 value) internal pure returns (bytes1) { if (value < 10) return bytes1(uint8(48 + (uint(value) % 10))); return bytes1(uint8(65 + uint256((value - 10) % 6))); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.20; import "../Breed.sol"; import "./ItemData.sol"; interface IGenerator { function get_item( Breed calldata seed_data ) external view returns (ItemData memory); function getSvg( Breed calldata seed_data ) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; import "../Breed.sol"; struct Rand { Breed breed; uint nonce; } library RandLib { function next(Rand memory rnd) internal pure returns (uint) { return uint( keccak256( abi.encodePacked( rnd.breed.serial_number, rnd.breed.breed2, rnd.nonce++ ) ) ); } function next_breed2_clamped(Rand memory rnd) internal pure returns (uint) { return next(rnd) % rnd.breed.breed2; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.21; struct ItemData { uint background_color; uint body; uint body_color; uint facial_hair; uint facial_hair_color; uint shirt_1; uint shirt_1_color; uint shirt_2; uint shirt_2_color; uint shirt_3; uint shirt_3_color; uint nose; uint nose_color; uint mouth; uint mouth_color; uint eyes_base_color; uint eyes; uint eyes_color; uint hair; uint hair_color; uint hat; uint hat_color; uint accessories; uint accessories_color; uint mask; uint mask_color; }
{ "remappings": [ "@openzeppelin/contracts/=lib/openzeppelin-contracts/contracts/", "ds-test/=lib/forge-std/lib/ds-test/src/", "erc4626-tests/=lib/openzeppelin-contracts/lib/erc4626-tests/", "forge-std/=lib/forge-std/src/", "openzeppelin-contracts/=lib/openzeppelin-contracts/", "v2-core/=lib/v2-core/contracts/", "v2-periphery/=lib/v2-periphery/contracts/" ], "optimizer": { "enabled": true, "runs": 200 }, "metadata": { "useLiteralContent": false, "bytecodeHash": "ipfs", "appendCBOR": true }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "evmVersion": "paris", "viaIR": false, "libraries": {} }
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"},{"inputs":[],"name":"ReentrancyGuardReentrantCall","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":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"GEN_MIN","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"accessories_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","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":"uint256","name":"","type":"uint256"}],"name":"background_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"body_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"breed_total_count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"breeds","outputs":[{"internalType":"uint256","name":"serial_number","type":"uint256"},{"internalType":"uint256","name":"breed2","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"counts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"eyes_base_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"eyes_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"facial_hair_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gen_max","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"serial_number","type":"uint256"},{"internalType":"uint256","name":"breed2","type":"uint256"}],"internalType":"struct Breed","name":"breed","type":"tuple"}],"name":"getSvg","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"get_account_breeds","outputs":[{"internalType":"uint256","name":"page_count","type":"uint256"},{"components":[{"internalType":"uint256","name":"serial_number","type":"uint256"},{"internalType":"uint256","name":"breed2","type":"uint256"}],"internalType":"struct Breed[]","name":"accounts","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"get_account_items","outputs":[{"internalType":"uint256","name":"page_count","type":"uint256"},{"components":[{"internalType":"uint256","name":"background_color","type":"uint256"},{"internalType":"uint256","name":"body","type":"uint256"},{"internalType":"uint256","name":"body_color","type":"uint256"},{"internalType":"uint256","name":"facial_hair","type":"uint256"},{"internalType":"uint256","name":"facial_hair_color","type":"uint256"},{"internalType":"uint256","name":"shirt_1","type":"uint256"},{"internalType":"uint256","name":"shirt_1_color","type":"uint256"},{"internalType":"uint256","name":"shirt_2","type":"uint256"},{"internalType":"uint256","name":"shirt_2_color","type":"uint256"},{"internalType":"uint256","name":"shirt_3","type":"uint256"},{"internalType":"uint256","name":"shirt_3_color","type":"uint256"},{"internalType":"uint256","name":"nose","type":"uint256"},{"internalType":"uint256","name":"nose_color","type":"uint256"},{"internalType":"uint256","name":"mouth","type":"uint256"},{"internalType":"uint256","name":"mouth_color","type":"uint256"},{"internalType":"uint256","name":"eyes_base_color","type":"uint256"},{"internalType":"uint256","name":"eyes","type":"uint256"},{"internalType":"uint256","name":"eyes_color","type":"uint256"},{"internalType":"uint256","name":"hair","type":"uint256"},{"internalType":"uint256","name":"hair_color","type":"uint256"},{"internalType":"uint256","name":"hat","type":"uint256"},{"internalType":"uint256","name":"hat_color","type":"uint256"},{"internalType":"uint256","name":"accessories","type":"uint256"},{"internalType":"uint256","name":"accessories_color","type":"uint256"},{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"mask_color","type":"uint256"}],"internalType":"struct ItemData[]","name":"accounts","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"get_account_svgs","outputs":[{"internalType":"uint256","name":"page_count","type":"uint256"},{"internalType":"string[]","name":"accounts","type":"string[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"get_holders_list","outputs":[{"internalType":"uint256","name":"page_count","type":"uint256"},{"internalType":"address[]","name":"accounts","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"serial_number","type":"uint256"},{"internalType":"uint256","name":"breed2","type":"uint256"}],"internalType":"struct Breed","name":"breed","type":"tuple"}],"name":"get_item","outputs":[{"components":[{"internalType":"uint256","name":"background_color","type":"uint256"},{"internalType":"uint256","name":"body","type":"uint256"},{"internalType":"uint256","name":"body_color","type":"uint256"},{"internalType":"uint256","name":"facial_hair","type":"uint256"},{"internalType":"uint256","name":"facial_hair_color","type":"uint256"},{"internalType":"uint256","name":"shirt_1","type":"uint256"},{"internalType":"uint256","name":"shirt_1_color","type":"uint256"},{"internalType":"uint256","name":"shirt_2","type":"uint256"},{"internalType":"uint256","name":"shirt_2_color","type":"uint256"},{"internalType":"uint256","name":"shirt_3","type":"uint256"},{"internalType":"uint256","name":"shirt_3_color","type":"uint256"},{"internalType":"uint256","name":"nose","type":"uint256"},{"internalType":"uint256","name":"nose_color","type":"uint256"},{"internalType":"uint256","name":"mouth","type":"uint256"},{"internalType":"uint256","name":"mouth_color","type":"uint256"},{"internalType":"uint256","name":"eyes_base_color","type":"uint256"},{"internalType":"uint256","name":"eyes","type":"uint256"},{"internalType":"uint256","name":"eyes_color","type":"uint256"},{"internalType":"uint256","name":"hair","type":"uint256"},{"internalType":"uint256","name":"hair_color","type":"uint256"},{"internalType":"uint256","name":"hat","type":"uint256"},{"internalType":"uint256","name":"hat_color","type":"uint256"},{"internalType":"uint256","name":"accessories","type":"uint256"},{"internalType":"uint256","name":"accessories_color","type":"uint256"},{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"mask_color","type":"uint256"}],"internalType":"struct ItemData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"get_item_acc_index","outputs":[{"components":[{"internalType":"uint256","name":"background_color","type":"uint256"},{"internalType":"uint256","name":"body","type":"uint256"},{"internalType":"uint256","name":"body_color","type":"uint256"},{"internalType":"uint256","name":"facial_hair","type":"uint256"},{"internalType":"uint256","name":"facial_hair_color","type":"uint256"},{"internalType":"uint256","name":"shirt_1","type":"uint256"},{"internalType":"uint256","name":"shirt_1_color","type":"uint256"},{"internalType":"uint256","name":"shirt_2","type":"uint256"},{"internalType":"uint256","name":"shirt_2_color","type":"uint256"},{"internalType":"uint256","name":"shirt_3","type":"uint256"},{"internalType":"uint256","name":"shirt_3_color","type":"uint256"},{"internalType":"uint256","name":"nose","type":"uint256"},{"internalType":"uint256","name":"nose_color","type":"uint256"},{"internalType":"uint256","name":"mouth","type":"uint256"},{"internalType":"uint256","name":"mouth_color","type":"uint256"},{"internalType":"uint256","name":"eyes_base_color","type":"uint256"},{"internalType":"uint256","name":"eyes","type":"uint256"},{"internalType":"uint256","name":"eyes_color","type":"uint256"},{"internalType":"uint256","name":"hair","type":"uint256"},{"internalType":"uint256","name":"hair_color","type":"uint256"},{"internalType":"uint256","name":"hat","type":"uint256"},{"internalType":"uint256","name":"hat_color","type":"uint256"},{"internalType":"uint256","name":"accessories","type":"uint256"},{"internalType":"uint256","name":"accessories_color","type":"uint256"},{"internalType":"uint256","name":"mask","type":"uint256"},{"internalType":"uint256","name":"mask_color","type":"uint256"}],"internalType":"struct ItemData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"get_svg_acc_index","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hair_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"hat_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"holders_count","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mask_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxBuy","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"max_breed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"mouth_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"nose_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"random_value","type":"uint256"},{"internalType":"uint256","name":"step","type":"uint256"}],"name":"pick_color_internal","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_accessories","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_body","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"step_base","type":"uint256"}],"name":"set_color_step_base","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_eyes","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_eyes_base","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_facial_hair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_hair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_hat","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_mask","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"max","type":"uint256"}],"name":"set_max_base","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_mouth","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_nose","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_shirt_1","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_shirt_2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"file","type":"uint256"},{"components":[{"internalType":"string","name":"fill","type":"string"},{"internalType":"string","name":"data","type":"string"}],"internalType":"struct Path[]","name":"paths","type":"tuple[]"}],"internalType":"struct FileData[]","name":"data","type":"tuple[]"}],"name":"set_shirt_3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"shirt_1_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"shirt_2_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"shirt_3_colors","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"pair","type":"address"}],"name":"start","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"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":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"transfer_breed_from_to_by_index","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
60076101e0818152662366663537333360c81b6102005260a090815261022082815266119999b198b33360c91b6102405260c052610260828152662366666363333360c81b6102805260e0526102a0828152662333336666353760c81b6102c052610100526102e082815266119c319999b33360c91b6103005261012052610320828152662366663333623560c81b6103405261014052610360828152662333336666636360c81b61038052610160526103a08281526608d9998cccce0d60ca1b6103c052610180526103e082815266119999b218b33360c91b610400526101a052610460604052610420918252662366666238333360c81b610440526101c09190915261011190600690600a6114c3565b50604080516101808101825260076101408201818152662366666536636360c81b610160840152825282518084018452818152662366666363393960c81b6020828101919091528084019190915283518085018552828152662366666431646360c81b818301528385015283518085018552828152662366306536386360c81b81830152606084015283518085018552828152662366666635656560c81b81830152608084015283518085018552828152660236530653065360cc1b8183015260a084015283518085018552828152662362306535376360c81b8183015260c0840152835180850185528281526611b3309c181b9960c91b8183015260e084015283518085018552828152662366666464393960c81b818301526101008401528351808501909452818452662366666661666160c81b908401526101208201929092526102609190600a6114c3565b50604080516101808101825260076101408201818152662365393936376160c81b610160840152825282518084018452818152662366663633343760c81b6020828101919091528084019190915283518085018552828152662366666130376160c81b818301528385015283518085018552828152662363643563356360c81b81830152606084015283518085018552828152662366356465623360c81b81830152608084015283518085018552828152662336393639363960c81b8183015260a084015283518085018552828152660467270ccc472760cb1b8183015260c084015283518085018552828152660236666343530360cc1b8183015260e084015283518085018552828152662364326234386360c81b818301526101008401528351808501909452908352662366666566643560c81b908301526101208101919091526103b190600890600a6114c3565b50604080516101808101825260076101408201818152662338623435313360c81b6101608401528252825180840184528181526608d84c0d4c8c9960ca1b6020828101919091528084019190915283518085018552828152662364323639316560c81b8183015283850152835180850185528281526611b1b21c1a99b360c91b818301526060840152835180850185528281526611b132311b9b3160c91b81830152608084015283518085018552828152662336393639363960c81b8183015260a084015283518085018552828152660233830383030360cc1b8183015260c084015283518085018552828152662366663633343760c81b8183015260e084015283518085018552828152660233862303030360cc1b818301526101008401528351808501909452908352662364326234386360c81b9083015261012081019190915261050290600990600a6114c3565b506040805161018081018252600761014082018181526611b318331c333360c91b6101608401528252825180840184528181526608cd0d8e0c988d60ca1b6020828101919091528084019190915283518085018552828152662366666534653160c81b8183015283850152835180850185528281526608d9999919585960ca1b81830152606084015283518085018552828152662365366536666160c81b81830152608084015283518085018552828152660233830383038360cc1b8183015260a0840152835180850185528281526611b330b330b21960c91b8183015260c084015283518085018552828152660236666376635360cc1b8183015260e084015283518085018552828152662366666638646360c81b818301526101008401528351808501909452908352660236330633063360cc1b9083015261012081019190915261065290600a90816114c3565b506040805161018081018252600761014082018181526608d9998d8e588d60ca1b6101608401528252825180840184528181526611b1191919191960c91b60208281019190915280840191909152835180850185528281526611b33233321c9b60c91b8183015283850152835180850185528281526608d919184c191960ca1b818301819052606085019190915284518086018652838152662366666236633160c81b81840152608085015284518086018652838152660236666343530360cc1b8184015260a08501528451808601865283815266119c309931329960c91b8184015260c0850152845180860186528381528083019190915260e084015283518085018552828152660467270ccc472760cb1b818301526101008401528351808501909452908352660236666643730360cc1b908301526101208101919091526107a090600b90600a6114c3565b50604080516101808101825260076101408201818152660233830303038360cc1b610160840152825282518084018452818152660233566396561360cc1b6020828101919091528084019190915283518085018552828152662366663633343760c81b81830152838501528351808501855282815266119a3118181c1960c91b81830152606084015283518085018552828152660233830303030360cc1b81830152608084015283518085018552828152660236666343530360cc1b8183015260a084015283518085018552828152661199331a331a3360c91b8183015260c084015283518085018552828152660233830383030360cc1b8183015260e084015283518085018552828152660233862303030360cc1b818301526101008401528351808501909452908352662364323639316560c81b908301526101208101919091526108f190600c90600a6114c3565b5060408051610180810182526007610140820181815266119c1bb1b2b2b160c91b6101608401528252825180840184528181526608d999999858d960ca1b6020828101919091528084019190915283518085018552828152660467270ccc472760cb1b8183015283850152835180850185528281526608d919184c191960ca1b818301526060840152835180850185528281526608d9998d8e588d60ca1b81830152608084015283518085018552828152662366616562643760c81b8183015260a084015283518085018552828152660236630383038360cc1b8183015260c084015283518085018552828152662361666565656560c81b8183015260e084015283518085018552828152662366356635663560c81b818301526101008401528351808501909452908352662366666461623960c81b90830152610120810191909152610a4290600d90600a6114c3565b50604080516101808101825260076101408201818152662364323639316560c81b610160840152825282518084018452818152662338623435313360c81b6020828101919091528084019190915283518085018552828152662364656238383760c81b818301528385015283518085018552828152662366663633343760c81b81830152606084015283518085018552828152660236461613532360cc1b81830152608084015283518085018552828152662365393936376160c81b8183015260a0840152835180850185528281526611b1b21c1a99b360c91b8183015260c084015283518085018552828152660233862303030360cc1b8183015260e084015283518085018552828152662366666130376160c81b8183015261010084015283518085019094529083526611b11c1c1b183160c91b90830152610120810191909152610b9390600e90600a6114c3565b50604080516101808101825260076101408201818152662364636463646360c81b6101608401528252825180840184528181526608cd0d8e0c988d60ca1b60208281019190915280840191909152835180850185528281526611999931b2199960c91b8183015283850152835180850185528281526608d9998d8e588d60ca1b81830152606084015283518085018552828152660236666343530360cc1b81830152608084015283518085018552828152662330306661396160c81b8183015260a084015283518085018552828152662366663633343760c81b8183015260c084015283518085018552828152660236666613530360cc1b8183015260e084015283518085018552828152662338376365666160c81b81830152610100840152835180850190945290835266119c999b98323160c91b90830152610120810191909152610ce490600f90600a6114c3565b50604080516101808101825260076101408201818152662338623435313360c81b6101608401528252825180840184528181526608d84c0d4c8c9960ca1b6020828101919091528084019190915283518085018552828152662364323639316560c81b8183015283850152835180850185528281526611b1b21c1a99b360c91b81830152606084015283518085018552828152660233830383038360cc1b81830152608084015283518085018552828152660233862303030360cc1b8183015260a0840152835180850185528281526611b11c1c1b183160c91b8183015260c084015283518085018552828152662336393639363960c81b8183015260e084015283518085018552828152660236461613532360cc1b818301526101008401528351808501909452908352660236666386330360cc1b90830152610120810191909152610e3590601090600a6114c3565b50604080516101808101825260076101408201818152660233030303030360cc1b610160840152825282518084018452818152662366663633343760c81b6020828101919091528084019190915283518085018552828152661198b29c98333360c91b8183015283850152835180850185528281526611999931b2199960c91b81830152606084015283518085018552828152660236666343530360cc1b81830152608084015283518085018552828152660236666643730360cc1b8183015260a08401528351808501855282815266119c309931329960c91b8183015260c084015283518085018552828152662366663134393360c81b8183015260e084015283518085018552828152662330306365643160c81b8183015261010084015283518085019094529083526608d9998d8e588d60ca1b90830152610120810191909152610f8690601190600a6114c3565b50604080516101808101825260076101408201818152662364323639316560c81b610160840152825282518084018452818152660236666343530360cc1b6020828101919091528084019190915283518085018552828152662332653862353760c81b8183015283850152835180850185528281526608cd0d8e0c988d60ca1b81830152606084015283518085018552828152662366663633343760c81b81830152608084015283518085018552828152662366663134393360c81b8183015260a084015283518085018552828152660233862303030360cc1b8183015260c0840152835180850185528281526608d919184c191960ca1b8183015260e084015283518085018552828152660236666643730360cc1b81830152610100840152835180850190945290835266119c309931329960c91b908301526101208101919091526110d790601290600a6114c3565b506040805161018081018252600761014082018181526611b3333333333360c91b610160840152825282518084018452818152660236634613436360cc1b6020828101919091528084019190915283518085018552828152662366663633343760c81b81830181905284860191909152845180860186528381526611b1191919191960c91b81840152606085015284518086018652838152660236666343530360cc1b81840152608085015284518086018652838152662338623435313360c81b8184015260a0850152845180860186528381526611b1319c331c3360c91b8184015260c0850152845180860186528381528083019190915260e084015283518085018552828152660236666666166360cc1b81830152610100840152835180850190945290835266119c309931329960c91b9083015261012081019190915261122590601390600a6114c3565b506103e86022556103e86023556103e8602a5534801561124457600080fd5b50604051806040016040528060078152602001664f74686569736d60c81b815250604051806040016040528060018152602001604f60f81b81525033828281600390816112919190611629565b50600461129e8282611629565b5050506001600160a01b0381166112d057604051631e4fbdf760e01b8152600060048201526024015b60405180910390fd5b6112d98161130d565b50336080819052611301906112f06009600a6117e4565b6112fc906103e86117fa565b61135f565b50506001602655611824565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0382166113895760405163ec442f0560e01b8152600060048201526024016112c7565b61139560008383611399565b5050565b6001600160a01b0383166113c45780600260008282546113b99190611811565b909155506114369050565b6001600160a01b038316600090815260208190526040902054818110156114175760405163391434e360e21b81526001600160a01b038516600482015260248101829052604481018390526064016112c7565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b03821661145257600280548290039055611471565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516114b691815260200190565b60405180910390a3505050565b828054828255906000526020600020908101928215611509579160200282015b8281111561150957825182906114f99082611629565b50916020019190600101906114e3565b50611515929150611519565b5090565b8082111561151557600061152d8282611536565b50600101611519565b5080546115429061159e565b6000825580601f10611552575050565b601f0160209004906000526020600020908101906115709190611573565b50565b5b808211156115155760008155600101611574565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806115b257607f821691505b6020821081036115d257634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115611624576000816000526020600020601f850160051c810160208610156116015750805b601f850160051c820191505b818110156116205782815560010161160d565b5050505b505050565b81516001600160401b0381111561164257611642611588565b61165681611650845461159e565b846115d8565b602080601f83116001811461168b57600084156116735750858301515b600019600386901b1c1916600185901b178555611620565b600085815260208120601f198616915b828110156116ba5788860151825594840194600190910190840161169b565b50858210156116d85787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b8085111561173957816000190482111561171f5761171f6116e8565b8085161561172c57918102915b93841c9390800290611703565b509250929050565b600082611750575060016117de565b8161175d575060006117de565b8160018114611773576002811461177d57611799565b60019150506117de565b60ff84111561178e5761178e6116e8565b50506001821b6117de565b5060208310610133831016604e8410600b84101617156117bc575081810a6117de565b6117c683836116fe565b80600019048211156117da576117da6116e8565b0290505b92915050565b60006117f360ff841683611741565b9392505050565b80820281158282048414176117de576117de6116e8565b808201808211156117de576117de6116e8565b60805161494561184d600039600081816103ba015281816120f0015261212c01526149456000f3fe6080604052600436106103b15760003560e01c80637673bfa4116101e7578063afd1e4d81161010d578063dd0b281e116100a0578063eb0ffeb81161006f578063eb0ffeb814610c27578063f2fde38b14610c47578063f578990e14610c67578063fe6fb9a014610c8757600080fd5b8063dd0b281e14610ba1578063dd62ed3e14610bc1578063dde415fa1461094e578063e7a966b614610c0757600080fd5b8063b4f243a4116100dc578063b4f243a414610b13578063bdc1827c14610b33578063c01e21af14610b53578063d5a4260614610b7357600080fd5b8063afd1e4d814610a9d578063b42781ee14610abd578063b42dfa0d14610add578063b4377a3e14610af357600080fd5b8063984bb7a611610185578063a46f3d4b11610154578063a46f3d4b14610a27578063a4ea3c3314610a47578063a9059cbb14610a67578063af504def14610a8757600080fd5b8063984bb7a61461099957806398bafaa3146109b95780639b439dc5146109e75780639c7d73e614610a0757600080fd5b80638da5cb5b116101c15780638da5cb5b146109265780638fdada4a1461094e578063943a6ff61461096457806395d89b411461098457600080fd5b80637673bfa4146108c65780637c3b3b87146108e657806387cd15551461090657600080fd5b8063422b9e23116102d75780636a29f5e51161026a578063719f150711610239578063719f150714610838578063719fa9b11461085857806374ae513614610878578063750e8d101461089857600080fd5b80636a29f5e51461078457806370a08231146107d857806370db69d61461080e578063715018a61461082357600080fd5b8063544736e6116102a6578063544736e6146107045780635534b159146107245780635e5b6dfd146107445780635e927ceb1461076457600080fd5b8063422b9e23146106845780634dc46def146106a457806353388fd5146106c457806353c55061146106e457600080fd5b806318160ddd1161034f578063313ce5671161031e578063313ce567146105ed57806336d208cf146106095780633860a393146106295780633fc0fdcb1461065757600080fd5b806318160ddd1461058357806323b872dd146105985780632547b84d146105b85780632d12d34b146105d857600080fd5b806306fdde031161038b57806306fdde03146104fe578063095ea7b3146105135780630dfa2c481461054357806312ac5d0f1461056357600080fd5b8063018a37411461047b5780630568e65e146104a457806306a86dd7146104d157600080fd5b366104765760007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03163460405160006040518083038185875af1925050503d8060008114610423576040519150601f19603f3d011682016040523d82523d6000602084013e610428565b606091505b505080915050806104745760405162461bcd60e51b815260206004820152601160248201527031b0b7103737ba1033b2ba1032ba3432b960791b60448201526064015b60405180910390fd5b005b600080fd5b34801561048757600080fd5b5061049160295481565b6040519081526020015b60405180910390f35b3480156104b057600080fd5b506104916104bf36600461395a565b602c6020526000908152604090205481565b3480156104dd57600080fd5b506104f16104ec366004613975565b610ca7565b60405161049b91906139de565b34801561050a57600080fd5b506104f1610d53565b34801561051f57600080fd5b5061053361052e3660046139f1565b610de5565b604051901515815260200161049b565b34801561054f57600080fd5b506104f161055e366004613975565b610dff565b34801561056f57600080fd5b506104f161057e366004613975565b610e0f565b34801561058f57600080fd5b50600254610491565b3480156105a457600080fd5b506105336105b3366004613a1b565b610e1f565b3480156105c457600080fd5b506104f16105d3366004613975565b610e45565b3480156105e457600080fd5b50610491600181565b3480156105f957600080fd5b506040516009815260200161049b565b34801561061557600080fd5b50610474610624366004613a57565b610e55565b34801561063557600080fd5b50610649610644366004613acc565b610e98565b60405161049b929190613aee565b34801561066357600080fd5b506106776106723660046139f1565b610fa0565b60405161049b9190613c58565b34801561069057600080fd5b506104f161069f366004613c67565b611038565b3480156106b057600080fd5b506104746106bf366004613a57565b6110b0565b3480156106d057600080fd5b506104f16106df366004613975565b6110f3565b3480156106f057600080fd5b506104f16106ff366004613975565b611103565b34801561071057600080fd5b506024546001600160a01b03161515610533565b34801561073057600080fd5b506104f161073f366004613975565b611113565b34801561075057600080fd5b5061047461075f366004613a57565b611123565b34801561077057600080fd5b5061047461077f366004613975565b611169565b34801561079057600080fd5b506107c361079f3660046139f1565b602b6020908152600092835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161049b565b3480156107e457600080fd5b506104916107f336600461395a565b6001600160a01b031660009081526020819052604090205490565b34801561081a57600080fd5b50610491611176565b34801561082f57600080fd5b50610474611273565b34801561084457600080fd5b50610474610853366004613a57565b611287565b34801561086457600080fd5b50610474610873366004613a57565b6112cc565b34801561088457600080fd5b506104f1610893366004613975565b611313565b3480156108a457600080fd5b506108b86108b3366004613c7f565b611323565b60405161049b929190613cb2565b3480156108d257600080fd5b506104f16108e1366004613975565b6114df565b3480156108f257600080fd5b50610677610901366004613c67565b6114ef565b34801561091257600080fd5b506104f1610921366004613975565b6118f8565b34801561093257600080fd5b506005546040516001600160a01b03909116815260200161049b565b34801561095a57600080fd5b506104916103e881565b34801561097057600080fd5b506104f161097f366004613975565b611908565b34801561099057600080fd5b506104f1611918565b3480156109a557600080fd5b506104746109b4366004613a57565b611927565b3480156109c557600080fd5b506109d96109d4366004613c7f565b611969565b60405161049b929190613d00565b3480156109f357600080fd5b50610474610a02366004613a57565b611ad9565b348015610a1357600080fd5b50610474610a22366004613a57565b611b1a565b348015610a3357600080fd5b50610474610a42366004613a57565b611b5d565b348015610a5357600080fd5b50610474610a62366004613a57565b611ba0565b348015610a7357600080fd5b50610533610a823660046139f1565b611be4565b348015610a9357600080fd5b50610491602d5481565b348015610aa957600080fd5b506104f1610ab8366004613975565b611bf2565b348015610ac957600080fd5b50610474610ad8366004613975565b611c02565b348015610ae957600080fd5b50610491602a5481565b348015610aff57600080fd5b50610474610b0e366004613d5b565b611c0f565b348015610b1f57600080fd5b506104f1610b2e3660046139f1565b611c6e565b348015610b3f57600080fd5b50610474610b4e366004613a57565b611ca8565b348015610b5f57600080fd5b50610491610b6e366004613d87565b611ceb565b348015610b7f57600080fd5b50610b93610b8e366004613c7f565b611d83565b60405161049b929190613db3565b348015610bad57600080fd5b50610474610bbc36600461395a565b611ef1565b348015610bcd57600080fd5b50610491610bdc366004613e1f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b348015610c1357600080fd5b506104f1610c22366004613975565b611f1f565b348015610c3357600080fd5b50610474610c42366004613a57565b611f2f565b348015610c5357600080fd5b50610474610c6236600461395a565b611f65565b348015610c7357600080fd5b506104f1610c82366004613975565b611fa3565b348015610c9357600080fd5b50610474610ca2366004613a57565b611fb3565b60078181548110610cb757600080fd5b906000526020600020016000915090508054610cd290613e49565b80601f0160208091040260200160405190810160405280929190818152602001828054610cfe90613e49565b8015610d4b5780601f10610d2057610100808354040283529160200191610d4b565b820191906000526020600020905b815481529060010190602001808311610d2e57829003601f168201915b505050505081565b606060038054610d6290613e49565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8e90613e49565b8015610ddb5780601f10610db057610100808354040283529160200191610ddb565b820191906000526020600020905b815481529060010190602001808311610dbe57829003601f168201915b5050505050905090565b600033610df3818585611ff6565b60019150505b92915050565b600a8181548110610cb757600080fd5b600c8181548110610cb757600080fd5b600033610e2d858285612008565b610e38858585612086565b60019150505b9392505050565b60108181548110610cb757600080fd5b610e5d6121d8565b602154610e7a90601790849084906301000000900460ff16612205565b602160036101000a81548160ff021916908360ff1602179055505050565b600060606029548410610ebc57505060408051600080825260208201909252610f99565b6000610ec88486613ea9565b9050602954811115610ed957506029545b610ee38582613ebc565b92508267ffffffffffffffff811115610efe57610efe613e7d565b604051908082528060200260200182016040528015610f27578160200160208202803683370190505b509150845b83811015610f965760276000610f428389613ea9565b815260200190815260200160002060009054906101000a90046001600160a01b0316838281518110610f7657610f76613ecf565b6001600160a01b0390921660209283029190910190910152600101610f2c565b50505b9250929050565b610fa86137ee565b6001600160a01b0383166000908152602b60209081526040808320858452909152908190209051637c3b3b8760e01b81528154600482015260019091015460248201523090637c3b3b879060440161034060405180830381865afa158015611014573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3e9190613f0f565b604051637c3b3b8760e01b81528135600482015260208201356024820152606090610df9903090637c3b3b87906044015b61034060405180830381865afa158015611087573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ab9190613f0f565b612265565b6110b86121d8565b6021546110d590601e9084908490600160501b900460ff16612205565b6021600a6101000a81548160ff021916908360ff1602179055505050565b60088181548110610cb757600080fd5b60098181548110610cb757600080fd5b60128181548110610cb757600080fd5b61112b6121d8565b60215461114b90601a90849084906601000000000000900460ff16612205565b602160066101000a81548160ff021916908360ff1602179055505050565b6111716121d8565b602355565b600061118c6024546001600160a01b0316151590565b6111ad5761119c6009600a614127565b6111a8906103e8614136565b905090565b60006127106001602554426111c29190613ebc565b6111ce6009600a614127565b6111da906103e8614136565b6111e49190614136565b6111ee9190614136565b6111f89190614163565b6127106112076009600a614127565b611213906103e8614136565b61121e906005614136565b6112289190614163565b6112329190613ea9565b90506112406009600a614127565b61124c906103e8614136565b81111561126e5761125f6009600a614127565b61126b906103e8614136565b90505b919050565b61127b6121d8565b61128560006124a3565b565b61128f6121d8565b6021546112ae906019908490849065010000000000900460ff16612205565b602160056101000a81548160ff021916908360ff1602179055505050565b6112d46121d8565b6021546112f590601b9084908490670100000000000000900460ff16612205565b602160076101000a81548160ff021916908360ff1602179055505050565b600d8181548110610cb757600080fd5b6001600160a01b0383166000908152602c6020526040812054606090808510611382576040805160008082526020820190925281611377565b6113646137ee565b81526020019060019003908161135c5790505b5092509250506114d7565b600061138e8587613ea9565b90508181111561139b5750805b6113a58682613ebc565b93508367ffffffffffffffff8111156113c0576113c0613e7d565b6040519080825280602002602001820160405280156113f957816020015b6113e66137ee565b8152602001906001900390816113de5790505b50925060005b848110156114d3576001600160a01b0388166000908152602b602052604081203091637c3b3b879190611432858c613ea9565b81526020019081526020016000206040518263ffffffff1660e01b815260040161146c919081548152600190910154602082015260400190565b61034060405180830381865afa15801561148a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ae9190613f0f565b8482815181106114c0576114c0613ecf565b60209081029190910101526001016113ff565b5050505b935093915050565b60068181548110610cb757600080fd5b6114f76137ee565b60006040518060400160405280848036038101906115159190614177565b8152602001600081525090506115296137ee565b600654611535836124f5565b61153f91906141c6565b81526021546115599060ff16611554846124f5565b61254b565b6020820152611580600761156c846124f5565b84516020015161157b90612562565b612584565b604082015260235461159490600390614163565b61159d83612594565b11156115d4576021546115bb90610100900460ff16611554846124f5565b60608201526115ce601061156c846124f5565b60808201525b6021546115ed9062010000900460ff16611554846124f5565b60a0820152600a546115fe836124f5565b61160891906141c6565b60c082015260235461161c90600390614163565b61162583612594565b111561165f57602154611645906301000000900460ff16611554846124f5565b60e0820152611658600b61156c846124f5565b6101008201525b600360235461166e9190614163565b61167783612594565b11156116b35760215461169890640100000000900460ff16611554846124f5565b6101208201526116ac600c61156c846124f5565b6101408201525b60036023546116c29190614163565b6116cb83612594565b1115611708576021546116ed9065010000000000900460ff16611554846124f5565b610160820152611701600961156c846124f5565b6101808201525b60036023546117179190614163565b61172083612594565b111561175e57602154611743906601000000000000900460ff16611554846124f5565b6101a0820152611757600861156c846124f5565b6101c08201525b61176c601161156c846124f5565b6101e082015260215461178c90600160401b900460ff16611554846124f5565b6102008201526117a0600d61156c846124f5565b6102208201526023546117b590600390614163565b6117be83612594565b11156117f9576021546117de90600160481b900460ff16611554846124f5565b6102408201526117f2600e61156c846124f5565b6102608201525b60036023546118089190614163565b61181183612594565b111561184c5760215461183190600160501b900460ff16611554846124f5565b610280820152611845601261156c846124f5565b6102a08201525b600360235461185b9190614163565b61186483612594565b111561189f5760215461188490600160581b900460ff16611554846124f5565b6102c0820152611898600f61156c846124f5565b6102e08201525b60036023546118ae9190614163565b6118b783612594565b1115610e3e576021546118d790600160601b900460ff16611554846124f5565b6103008201526118eb601361156c846124f5565b6103208201529392505050565b60118181548110610cb757600080fd5b600e8181548110610cb757600080fd5b606060048054610d6290613e49565b61192f6121d8565b60215461194b906016908490849062010000900460ff16612205565b602160026101000a81548160ff021916908360ff1602179055505050565b6001600160a01b0383166000908152602c60205260408120546060908085106119d3576040805160008082526020820190925281611377565b60408051808201909152600080825260208201528152602001906001900390816119a25790505092509250506114d7565b60006119df8587613ea9565b9050818111156119ec5750805b6119f68682613ebc565b93508367ffffffffffffffff811115611a1157611a11613e7d565b604051908082528060200260200182016040528015611a5657816020015b6040805180820190915260008082526020820152815260200190600190039081611a2f5790505b50925060005b848110156114d3576001600160a01b0388166000908152602b6020526040812090611a87838a613ea9565b815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050848281518110611ac657611ac6613ecf565b6020908102919091010152600101611a5c565b611ae16121d8565b602154611afc9060159084908490610100900460ff16612205565b602160016101000a81548160ff021916908360ff1602179055505050565b611b226121d8565b602154611b3f9060209084908490600160601b900460ff16612205565b6021600c6101000a81548160ff021916908360ff1602179055505050565b611b656121d8565b602154611b8290601c9084908490600160401b900460ff16612205565b602160086101000a81548160ff021916908360ff1602179055505050565b611ba86121d8565b602154611bc69060189084908490640100000000900460ff16612205565b602160046101000a81548160ff021916908360ff1602179055505050565b600033610df3818585612086565b60138181548110610cb757600080fd5b611c0a6121d8565b602255565b336000908152602c60205260409020548210611c5f5760405162461bcd60e51b815260206004820152600f60248201526e0d2dcc6dee4e4cac6e840d2dcc8caf608b1b604482015260640161046b565b611c6a3383836125b0565b5050565b604051633fc0fdcb60e01b81526001600160a01b038316600482015260248101829052606090610e3e903090633fc0fdcb90604401611069565b611cb06121d8565b602154611ccd90601d9084908490600160481b900460ff16612205565b602160096101000a81548160ff021916908360ff1602179055505050565b600080805b85811015611d215783611d038183614136565b611d0d9190613ea9565b611d179083613ea9565b9150600101611cf0565b611d2b82866141c6565b945060009150600090505b85811015611d775783611d498183614136565b611d539190613ea9565b611d5d9083613ea9565b9150848210611d6f579150610e3e9050565b600101611d36565b50600095945050505050565b6001600160a01b0383166000908152602c6020526040812054606090808510611ddb576040805160008082526020820190925281611377565b6060815260200190600190039081611dbc5790505092509250506114d7565b6000611de78587613ea9565b905081811115611e00575080611dfd8187613ebc565b93505b8367ffffffffffffffff811115611e1957611e19613e7d565b604051908082528060200260200182016040528015611e4c57816020015b6060815260200190600190039081611e375790505b5092508560005b82821015611ee5576001600160a01b0389166000908152602b60209081526040808320858452909152908190209051637c3b3b8760e01b8152815460048201526001909101546024820152611eb2903090637c3b3b8790604401611069565b8582611ebd816141da565b935081518110611ecf57611ecf613ecf565b6020026020010181905250816001019150611e53565b50505050935093915050565b611ef96121d8565b602480546001600160a01b0319166001600160a01b039290921691909117905542602555565b600f8181548110610cb757600080fd5b611f376121d8565b602154611f4d906014908490849060ff16612205565b6021805460ff191660ff929092169190911790555050565b611f6d6121d8565b6001600160a01b038116611f9757604051631e4fbdf760e01b81526000600482015260240161046b565b611fa0816124a3565b50565b600b8181548110610cb757600080fd5b611fbb6121d8565b602154611fd890601f9084908490600160581b900460ff16612205565b6021600b6101000a81548160ff021916908360ff1602179055505050565b6120038383836001612612565b505050565b6001600160a01b038381166000908152600160209081526040808320938616835292905220546000198114612080578181101561207157604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161046b565b61208084848484036000612612565b50505050565b6001600160a01b03821615806120a657506001600160a01b03821661dead145b156120b6576120038383836126e7565b6024546001600160a01b031615801561216057506001600160a01b03831615806120e857506001600160a01b03831630145b8061212457507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316836001600160a01b0316145b8061216057507f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316826001600160a01b0316145b156121705761200383838361292b565b602454600160a01b900460ff161561218d5761200383838361292b565b6024546001600160a01b03908116908416036121ad57612003828261298a565b6024546001600160a01b03908116908316036121cd576120038382612a5d565b6120038383836126e7565b6005546001600160a01b031633146112855760405163118cdaa760e01b815233600482015260240161046b565b600082810361221557508061225d565b60005b838110156122585761224e8686868481811061223657612236613ecf565b905060200281019061224891906141f3565b85612b7a565b9250600101612218565b829150505b949350505050565b60606000612273600a612c4a565b61227d600a612c4a565b60405160200161228e929190614213565b60408051601f1981840301815291905290506000816122ad600a612c4a565b6122b7600a612c4a565b60068760000151815481106122ce576122ce613ecf565b906000526020600020016040516020016122ea939291906142ae565b60405160208183030381529060405261230f6014600788602001518960400151612d4b565b6123256016600a8960a001518a60c00151612d4b565b61233b601560108a606001518b60800151612d4b565b6123526017600b8b60e001518c6101000151612d4b565b61236a6018600c8c61012001518d6101400151612d4b565b612382601960098d61016001518e6101800151612d4b565b61239a601a60088e6101a001518f6101c00151612d4b565b6040516020016123b2999897969594939291906143be565b604051602081830303815290604052905060006123d9601b60116001886101e00151612d4b565b6123f1601c600d886102000151896102200151612d4b565b612409601d600e8961024001518a6102600151612d4b565b612421601e60128a61028001518b6102a00151612d4b565b612439602060138b61030001518c6103200151612d4b565b612451601f600f8c6102c001518d6102e00151612e47565b6040516020016124669695949392919061447f565b6040516020818303038152906040529050818160405160200161248a9291906144fe565b6040516020818303038152906040529350505050919050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80518051602091820151918301805160009391612511826141da565b9052604080516020810194909452830191909152606082015260800160408051601f19818403018152919052805160209091012092915050565b600061255783836141c6565b610e3e906001613ea9565b600060225482101561257c5781602254610df99190613ebc565b506001919050565b825460009061225d908484611ceb565b8051602001516000906125a6836124f5565b610df991906141c6565b6001600160a01b0383166000908152602b6020908152604080832085845282529182902082518084019093528054835260010154908201526125fe84836125f96009600a614127565b612e99565b6126088484612efd565b6120808282613007565b6001600160a01b03841661263c5760405163e602df0560e01b81526000600482015260240161046b565b6001600160a01b03831661266657604051634a1406b160e11b81526000600482015260240161046b565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561208057826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516126d991815260200190565b60405180910390a350505050565b6126ef6130cc565b6001600160a01b038316600090815260208190526040812054906127138383613ebc565b90506000612736856001600160a01b031660009081526020819052604090205490565b905060006127448583613ea9565b90506001600160a01b038616158061276657506001600160a01b03861661dead145b15612772575060009050805b60006127806009600a614127565b61278a9085614163565b6127966009600a614127565b6127a09087614163565b6127aa9190613ebc565b905060006127ba6009600a614127565b6127c49085614163565b6127d06009600a614127565b6127da9085614163565b6127e49190613ebc565b905081818111156127f25750805b6001600160a01b038a166000908152602c60205260408120545b828210156128845780156128845760006128258261453e565b6001600160a01b038e166000908152602b60209081526040808320848452825291829020825180840190935280548352600101549082015290925082915061286d8e83612efd565b6128778d82613007565b505081600101915061280c565b82915b858310156128b557600061289a8361453e565b92508290506128a98e82612efd565b50826001019250612887565b8092505b8483101561290c5760006040518060400160405280602e600081546128dd906141da565b918290555081526020016128f26103e86130f6565b905290506129008d82613007565b508260010192506128b9565b6129178d8d8d612e99565b505050505050505050506120036001602655565b6001600160a01b03831661295557604051634b637e8f60e11b81526000600482015260240161046b565b6001600160a01b03821661297f5760405163ec442f0560e01b81526000600482015260240161046b565b612003838383613145565b6129926130cc565b6001600160a01b038216600090815260208190526040812054906129b68383613ea9565b905060006129c66009600a614127565b6129d09084614163565b6129dc6009600a614127565b6129e69084614163565b6129f09190613ebc565b905060005b81811015612a455760006040518060400160405280602e60008154612a19906141da565b91829055508152602001612a2e6103e86130f6565b90529050612a3c8782613007565b506001016129f5565b612a4f868661326f565b50505050611c6a6001602655565b6024805460ff60a01b1916600160a01b179055612a786130cc565b6001600160a01b03821660009081526020819052604081205490612a9c8383613ebc565b90506000612aac6009600a614127565b612ab69083614163565b612ac26009600a614127565b612acc9085614163565b612ad69190613ebc565b6001600160a01b0386166000908152602c6020526040812054919250905b82821015612b42576103e8602a541015612b1c57602a60008154612b17906141da565b909155505b8015612b3757612b3787612b2f8361453e565b925082612efd565b816001019150612af4565b602454612b5a9088906001600160a01b031688612086565b5050505050612b696001602655565b50506024805460ff60a01b19169055565b81356000908152602084905260408120805415612bbf57846000612ba060018735613ebc565b81526020019081526020016000206000612bba91906138b1565b612bcb565b612bc883614555565b92505b60005b612bdb6020860186614574565b9050811015612c405781612bf26020870187614574565b83818110612c0257612c02613ecf565b9050602002810190612c1491906141f3565b815460018101835560009283526020909220909160020201612c368282614716565b5050600101612bce565b5091949350505050565b606081600003612c715750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612c9b5780612c85816141da565b9150612c949050600a83614163565b9150612c75565b60008167ffffffffffffffff811115612cb657612cb6613e7d565b6040519080825280601f01601f191660200182016040528015612ce0576020820181803683370190505b5090505b841561225d57612cf5600183613ebc565b9150612d02600a866141c6565b612d0d906030613ea9565b60f81b818381518110612d2257612d22613ecf565b60200101906001600160f81b031916908160001a905350612d44600a86614163565b9450612ce4565b606082600003612d6a575060408051602081019091526000815261225d565b612e3e848381548110612d7f57612d7f613ecf565b906000526020600020018054612d9490613e49565b80601f0160208091040260200160405190810160405280929190818152602001828054612dc090613e49565b8015612e0d5780601f10612de257610100808354040283529160200191612e0d565b820191906000526020600020905b815481529060010190602001808311612df057829003601f168201915b5050505050866000600187612e229190613ebc565b81526020019081526020016000206132da90919063ffffffff16565b95945050505050565b606082600003612e66575060408051602081019091526000815261225d565b82600103612d6a57612e92856000612e7f600187613ebc565b815260200190815260200160002061347e565b905061225d565b6024805460ff60a01b1916600160a01b1790556001600160a01b0382161580612ecc57506001600160a01b03821661dead145b15612ee057612edb8382613617565b612eeb565b612eeb83838361292b565b50506024805460ff60a01b1916905550565b6024546001600160a01b0390811690831603612f17575050565b6001600160a01b0382166000908152602c602052604081208054909190612f3d9061453e565b9182905550600003612f5257612f528261364d565b602d60008154612f619061453e565b909155506001600160a01b0382166000908152602c6020526040902054818114612fd5576001600160a01b0383166000908152602b60209081526040808320848452808352818420825180840184528154815260019182015481860190815288875292909452919093209151825591519101555b6001600160a01b039092166000908152602b602090815260408083209483529390529182208281556001019190915550565b6024546001600160a01b0390811690831603613021575050565b6001600160a01b0382166000908152602c602052604081208054909190613047906141da565b918290555060010361305c5761305c82613734565b602d6000815461306b906141da565b909155506001600160a01b0382166000908152602c602052604081205461309490600190613ebc565b6001600160a01b03939093166000908152602b6020908152604080832095835294815293902082518155919092015160019091015550565b6002602654036130ef57604051633ee5aeb560e01b815260040160405180910390fd5b6002602655565b60006103e8602a54836131099190614136565b6131139190614163565b91508160000361312257600191505b6001602a54111561314157602a6000815461313c9061453e565b909155505b5090565b6001600160a01b0383166131705780600260008282546131659190613ea9565b909155506131e29050565b6001600160a01b038316600090815260208190526040902054818110156131c35760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161046b565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166131fe5760028054829003905561321d565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161326291815260200190565b60405180910390a3505050565b80613278611176565b8111156132b15760405162461bcd60e51b81526020600482015260076024820152666d61782062757960c81b604482015260640161046b565b6024805460ff60a01b198116600160a01b17909155612eeb906001600160a01b0316848461292b565b60608060005b8454811015613476578161344b8587848154811061330057613300613ecf565b906000526020600020906002020160405180604001604052908160008201805461332990613e49565b80601f016020809104026020016040519081016040528092919081815260200182805461335590613e49565b80156133a25780601f10613377576101008083540402835291602001916133a2565b820191906000526020600020905b81548152906001019060200180831161338557829003601f168201915b505050505081526020016001820180546133bb90613e49565b80601f01602080910402602001604051908101604052809291908181526020018280546133e790613e49565b80156134345780601f1061340957610100808354040283529160200191613434565b820191906000526020600020905b81548152906001019060200180831161341757829003601f168201915b50505050508152505061378990919063ffffffff16565b60405160200161345c9291906147f9565b60408051601f1981840301815291905291506001016132e0565b509392505050565b60608060005b835481101561361057816135e58583815481106134a3576134a3613ecf565b90600052602060002090600202016040518060400160405290816000820180546134cc90613e49565b80601f01602080910402602001604051908101604052809291908181526020018280546134f890613e49565b80156135455780601f1061351a57610100808354040283529160200191613545565b820191906000526020600020905b81548152906001019060200180831161352857829003601f168201915b5050505050815260200160018201805461355e90613e49565b80601f016020809104026020016040519081016040528092919081815260200182805461358a90613e49565b80156135d75780601f106135ac576101008083540402835291602001916135d7565b820191906000526020600020905b8154815290600101906020018083116135ba57829003601f168201915b5050505050815250506137bb565b6040516020016135f69291906147f9565b60408051601f198184030181529190529150600101613484565b5092915050565b6001600160a01b03821661364157604051634b637e8f60e11b81526000600482015260240161046b565b611c6a82600083613145565b60295460000361365a5750565b6001600160a01b03811660009081526028602052604090205460295461368290600190613ebc565b81146136e757600060276000600160295461369d9190613ebc565b815260208082019290925260409081016000908120548582526027845282822080546001600160a01b0319166001600160a01b039092169182179055815260289092529020829055505b6029600081546136f69061453e565b90915550506001600160a01b0316600090815260286020908152604080832083905560295483526027909152902080546001600160a01b0319169055565b6029805460009182613745836141da565b90915550600081815260276020908152604080832080546001600160a01b039097166001600160a01b03199097168717905594825260289052929092209190915550565b6060818360200151836040516020016137a493929190614828565b604051602081830303815290604052905092915050565b6060816000015182602001516040516020016137d89291906148a7565b6040516020818303038152906040529050919050565b60405180610340016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5080546000825560020290600052602060002090810190611fa091905b808211156131415760006138e282826138f9565b6138f06001830160006138f9565b506002016138ce565b50805461390590613e49565b6000825580601f10613915575050565b601f016020900490600052602060002090810190611fa091905b80821115613141576000815560010161392f565b80356001600160a01b038116811461126e57600080fd5b60006020828403121561396c57600080fd5b610e3e82613943565b60006020828403121561398757600080fd5b5035919050565b60005b838110156139a9578181015183820152602001613991565b50506000910152565b600081518084526139ca81602086016020860161398e565b601f01601f19169290920160200192915050565b602081526000610e3e60208301846139b2565b60008060408385031215613a0457600080fd5b613a0d83613943565b946020939093013593505050565b600080600060608486031215613a3057600080fd5b613a3984613943565b9250613a4760208501613943565b9150604084013590509250925092565b60008060208385031215613a6a57600080fd5b823567ffffffffffffffff80821115613a8257600080fd5b818501915085601f830112613a9657600080fd5b813581811115613aa557600080fd5b8660208260051b8501011115613aba57600080fd5b60209290920196919550909350505050565b60008060408385031215613adf57600080fd5b50508035926020909101359150565b60006040820184835260206040602085015281855180845260608601915060208701935060005b81811015613b3a5784516001600160a01b031683529383019391830191600101613b15565b5090979650505050505050565b805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e08082015190830152610200808201519083015261022080820151908301526102408082015190830152610260808201519083015261028080820151908301526102a080820151908301526102c080820151908301526102e08082015190830152610300808201519083015261032090810151910152565b6103408101610df98284613b47565b600060408284031215613c7957600080fd5b50919050565b600080600060608486031215613c9457600080fd5b613c9d84613943565b95602085013595506040909401359392505050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b81811015613b3a57613cec838651613b47565b938301936103409290920191600101613cd9565b6000604080830185845260206040602086015281865180845260608701915060208801935060005b81811015613d4d57845180518452840151848401529383019391850191600101613d28565b509098975050505050505050565b60008060408385031215613d6e57600080fd5b82359150613d7e60208401613943565b90509250929050565b600080600060608486031215613d9c57600080fd5b505081359360208301359350604090920135919050565b60006040820184835260206040602085015281855180845260608601915060608160051b87010193506020870160005b82811015613e1157605f19888703018452613dff8683516139b2565b95509284019290840190600101613de3565b509398975050505050505050565b60008060408385031215613e3257600080fd5b613e3b83613943565b9150613d7e60208401613943565b600181811c90821680613e5d57607f821691505b602082108103613c7957634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610df957610df9613e93565b81810381811115610df957610df9613e93565b634e487b7160e01b600052603260045260246000fd5b604051610340810167ffffffffffffffff81118282101715613f0957613f09613e7d565b60405290565b60006103408284031215613f2257600080fd5b613f2a613ee5565b825181526020808401519082015260408084015190820152606080840151908201526080808401519082015260a0808401519082015260c0808401519082015260e08084015190820152610100808401519082015261012080840151908201526101408084015190820152610160808401519082015261018080840151908201526101a080840151908201526101c080840151908201526101e08084015190820152610200808401519082015261022080840151908201526102408084015190820152610260808401519082015261028080840151908201526102a080840151908201526102c080840151908201526102e080840151908201526103008084015190820152610320928301519281019290925250919050565b600181815b8085111561407e57816000190482111561406457614064613e93565b8085161561407157918102915b93841c9390800290614048565b509250929050565b60008261409557506001610df9565b816140a257506000610df9565b81600181146140b857600281146140c2576140de565b6001915050610df9565b60ff8411156140d3576140d3613e93565b50506001821b610df9565b5060208310610133831016604e8410600b8410161715614101575081810a610df9565b61410b8383614043565b806000190482111561411f5761411f613e93565b029392505050565b6000610e3e60ff841683614086565b8082028115828204841417610df957610df9613e93565b634e487b7160e01b600052601260045260246000fd5b6000826141725761417261414d565b500490565b60006040828403121561418957600080fd5b6040516040810181811067ffffffffffffffff821117156141ac576141ac613e7d565b604052823581526020928301359281019290925250919050565b6000826141d5576141d561414d565b500690565b6000600182016141ec576141ec613e93565b5060010190565b60008235603e1983360301811261420957600080fd5b9190910192915050565b7f3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f3230815273030302f737667272076696577426f783d273020360641b60208201526000600160fd1b806034840152845161427381603586016020890161398e565b80840190508160358201528451915061429382603683016020880161398e565b61139f60f11b91016036810191909152603801949350505050565b703c7265637420783d27302720793d27302760781b8152672077696474683d2760c01b60118201526000845160206142ed826019860160208a0161398e565b6927206865696768743d2760b01b6019928501928301528551614317816023850160208a0161398e565b80830192505067272066696c6c3d2760c01b6023830152602b6000865461433d81613e49565b600182811680156143555760018114614370576143a2565b60ff198416602b890152602b831515840289010194506143a2565b8a600052602060002060005b848110156143975781548a820189015290830190880161437c565b5050602b8389010194505b50506213979f60e91b8352505060030198975050505050505050565b60008a516143d0818460208f0161398e565b8a516143e28183860160208f0161398e565b8a5191840101906143f7818360208e0161398e565b89516144098183850160208e0161398e565b895192909101019061441f818360208c0161398e565b87516144318183850160208c0161398e565b8751929091010190614447818360208a0161398e565b85516144598183850160208a0161398e565b855192909101019061446f81836020880161398e565b019b9a5050505050505050505050565b6000875160206144928285838d0161398e565b8851918401916144a58184848d0161398e565b88519201916144b78184848c0161398e565b87519201916144c98184848b0161398e565b86519201916144db8184848a0161398e565b85519201916144ed818484890161398e565b919091019998505050505050505050565b6000835161451081846020880161398e565b83519083019061452481836020880161398e565b651e17b9bb339f60d11b9101908152600601949350505050565b60008161454d5761454d613e93565b506000190190565b600060ff821660ff810361456b5761456b613e93565b60010192915050565b6000808335601e1984360301811261458b57600080fd5b83018035915067ffffffffffffffff8211156145a657600080fd5b6020019150600581901b3603821315610f9957600080fd5b6000808335601e198436030181126145d557600080fd5b83018035915067ffffffffffffffff8211156145f057600080fd5b602001915036819003821315610f9957600080fd5b601f821115612003576000816000526020600020601f850160051c8101602086101561462e5750805b601f850160051c820191505b8181101561464d5782815560010161463a565b505050505050565b67ffffffffffffffff83111561466d5761466d613e7d565b6146818361467b8354613e49565b83614605565b6000601f8411600181146146b5576000851561469d5750838201355b600019600387901b1c1916600186901b17835561470f565b600083815260209020601f19861690835b828110156146e657868501358255602094850194600190920191016146c6565b50868210156147035760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61472082836145be565b67ffffffffffffffff81111561473857614738613e7d565b61474c816147468554613e49565b85614605565b6000601f82116001811461478057600083156147685750838201355b600019600385901b1c1916600184901b1785556147da565b600085815260209020601f19841690835b828110156147b15786850135825560209485019460019092019101614791565b50848210156147ce5760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506147eb60208301836145be565b612080818360018601614655565b6000835161480b81846020880161398e565b83519083019061481f81836020880161398e565b01949350505050565b6b3c706174682066696c6c3d2760a01b81526000845161484f81600c85016020890161398e565b642720643d2760d81b600c91840191820152845161487481601184016020890161398e565b845191019061488a81601184016020880161398e565b6213979f60e91b6011929091019182015260140195945050505050565b6b3c706174682066696c6c3d2760a01b8152600083516148ce81600c85016020880161398e565b642720643d2760d81b600c9184019182015283516148f381601184016020880161398e565b6213979f60e91b6011929091019182015260140194935050505056fea2646970667358221220899f393b6cf7d8ceaa63105592e572691d18892b3a0ae9bcac147673f25286cf64736f6c63430008190033
Deployed Bytecode
0x6080604052600436106103b15760003560e01c80637673bfa4116101e7578063afd1e4d81161010d578063dd0b281e116100a0578063eb0ffeb81161006f578063eb0ffeb814610c27578063f2fde38b14610c47578063f578990e14610c67578063fe6fb9a014610c8757600080fd5b8063dd0b281e14610ba1578063dd62ed3e14610bc1578063dde415fa1461094e578063e7a966b614610c0757600080fd5b8063b4f243a4116100dc578063b4f243a414610b13578063bdc1827c14610b33578063c01e21af14610b53578063d5a4260614610b7357600080fd5b8063afd1e4d814610a9d578063b42781ee14610abd578063b42dfa0d14610add578063b4377a3e14610af357600080fd5b8063984bb7a611610185578063a46f3d4b11610154578063a46f3d4b14610a27578063a4ea3c3314610a47578063a9059cbb14610a67578063af504def14610a8757600080fd5b8063984bb7a61461099957806398bafaa3146109b95780639b439dc5146109e75780639c7d73e614610a0757600080fd5b80638da5cb5b116101c15780638da5cb5b146109265780638fdada4a1461094e578063943a6ff61461096457806395d89b411461098457600080fd5b80637673bfa4146108c65780637c3b3b87146108e657806387cd15551461090657600080fd5b8063422b9e23116102d75780636a29f5e51161026a578063719f150711610239578063719f150714610838578063719fa9b11461085857806374ae513614610878578063750e8d101461089857600080fd5b80636a29f5e51461078457806370a08231146107d857806370db69d61461080e578063715018a61461082357600080fd5b8063544736e6116102a6578063544736e6146107045780635534b159146107245780635e5b6dfd146107445780635e927ceb1461076457600080fd5b8063422b9e23146106845780634dc46def146106a457806353388fd5146106c457806353c55061146106e457600080fd5b806318160ddd1161034f578063313ce5671161031e578063313ce567146105ed57806336d208cf146106095780633860a393146106295780633fc0fdcb1461065757600080fd5b806318160ddd1461058357806323b872dd146105985780632547b84d146105b85780632d12d34b146105d857600080fd5b806306fdde031161038b57806306fdde03146104fe578063095ea7b3146105135780630dfa2c481461054357806312ac5d0f1461056357600080fd5b8063018a37411461047b5780630568e65e146104a457806306a86dd7146104d157600080fd5b366104765760007f00000000000000000000000080c03e5904ed45ab34d6c14daee6c96bf3ec81446001600160a01b03163460405160006040518083038185875af1925050503d8060008114610423576040519150601f19603f3d011682016040523d82523d6000602084013e610428565b606091505b505080915050806104745760405162461bcd60e51b815260206004820152601160248201527031b0b7103737ba1033b2ba1032ba3432b960791b60448201526064015b60405180910390fd5b005b600080fd5b34801561048757600080fd5b5061049160295481565b6040519081526020015b60405180910390f35b3480156104b057600080fd5b506104916104bf36600461395a565b602c6020526000908152604090205481565b3480156104dd57600080fd5b506104f16104ec366004613975565b610ca7565b60405161049b91906139de565b34801561050a57600080fd5b506104f1610d53565b34801561051f57600080fd5b5061053361052e3660046139f1565b610de5565b604051901515815260200161049b565b34801561054f57600080fd5b506104f161055e366004613975565b610dff565b34801561056f57600080fd5b506104f161057e366004613975565b610e0f565b34801561058f57600080fd5b50600254610491565b3480156105a457600080fd5b506105336105b3366004613a1b565b610e1f565b3480156105c457600080fd5b506104f16105d3366004613975565b610e45565b3480156105e457600080fd5b50610491600181565b3480156105f957600080fd5b506040516009815260200161049b565b34801561061557600080fd5b50610474610624366004613a57565b610e55565b34801561063557600080fd5b50610649610644366004613acc565b610e98565b60405161049b929190613aee565b34801561066357600080fd5b506106776106723660046139f1565b610fa0565b60405161049b9190613c58565b34801561069057600080fd5b506104f161069f366004613c67565b611038565b3480156106b057600080fd5b506104746106bf366004613a57565b6110b0565b3480156106d057600080fd5b506104f16106df366004613975565b6110f3565b3480156106f057600080fd5b506104f16106ff366004613975565b611103565b34801561071057600080fd5b506024546001600160a01b03161515610533565b34801561073057600080fd5b506104f161073f366004613975565b611113565b34801561075057600080fd5b5061047461075f366004613a57565b611123565b34801561077057600080fd5b5061047461077f366004613975565b611169565b34801561079057600080fd5b506107c361079f3660046139f1565b602b6020908152600092835260408084209091529082529020805460019091015482565b6040805192835260208301919091520161049b565b3480156107e457600080fd5b506104916107f336600461395a565b6001600160a01b031660009081526020819052604090205490565b34801561081a57600080fd5b50610491611176565b34801561082f57600080fd5b50610474611273565b34801561084457600080fd5b50610474610853366004613a57565b611287565b34801561086457600080fd5b50610474610873366004613a57565b6112cc565b34801561088457600080fd5b506104f1610893366004613975565b611313565b3480156108a457600080fd5b506108b86108b3366004613c7f565b611323565b60405161049b929190613cb2565b3480156108d257600080fd5b506104f16108e1366004613975565b6114df565b3480156108f257600080fd5b50610677610901366004613c67565b6114ef565b34801561091257600080fd5b506104f1610921366004613975565b6118f8565b34801561093257600080fd5b506005546040516001600160a01b03909116815260200161049b565b34801561095a57600080fd5b506104916103e881565b34801561097057600080fd5b506104f161097f366004613975565b611908565b34801561099057600080fd5b506104f1611918565b3480156109a557600080fd5b506104746109b4366004613a57565b611927565b3480156109c557600080fd5b506109d96109d4366004613c7f565b611969565b60405161049b929190613d00565b3480156109f357600080fd5b50610474610a02366004613a57565b611ad9565b348015610a1357600080fd5b50610474610a22366004613a57565b611b1a565b348015610a3357600080fd5b50610474610a42366004613a57565b611b5d565b348015610a5357600080fd5b50610474610a62366004613a57565b611ba0565b348015610a7357600080fd5b50610533610a823660046139f1565b611be4565b348015610a9357600080fd5b50610491602d5481565b348015610aa957600080fd5b506104f1610ab8366004613975565b611bf2565b348015610ac957600080fd5b50610474610ad8366004613975565b611c02565b348015610ae957600080fd5b50610491602a5481565b348015610aff57600080fd5b50610474610b0e366004613d5b565b611c0f565b348015610b1f57600080fd5b506104f1610b2e3660046139f1565b611c6e565b348015610b3f57600080fd5b50610474610b4e366004613a57565b611ca8565b348015610b5f57600080fd5b50610491610b6e366004613d87565b611ceb565b348015610b7f57600080fd5b50610b93610b8e366004613c7f565b611d83565b60405161049b929190613db3565b348015610bad57600080fd5b50610474610bbc36600461395a565b611ef1565b348015610bcd57600080fd5b50610491610bdc366004613e1f565b6001600160a01b03918216600090815260016020908152604080832093909416825291909152205490565b348015610c1357600080fd5b506104f1610c22366004613975565b611f1f565b348015610c3357600080fd5b50610474610c42366004613a57565b611f2f565b348015610c5357600080fd5b50610474610c6236600461395a565b611f65565b348015610c7357600080fd5b506104f1610c82366004613975565b611fa3565b348015610c9357600080fd5b50610474610ca2366004613a57565b611fb3565b60078181548110610cb757600080fd5b906000526020600020016000915090508054610cd290613e49565b80601f0160208091040260200160405190810160405280929190818152602001828054610cfe90613e49565b8015610d4b5780601f10610d2057610100808354040283529160200191610d4b565b820191906000526020600020905b815481529060010190602001808311610d2e57829003601f168201915b505050505081565b606060038054610d6290613e49565b80601f0160208091040260200160405190810160405280929190818152602001828054610d8e90613e49565b8015610ddb5780601f10610db057610100808354040283529160200191610ddb565b820191906000526020600020905b815481529060010190602001808311610dbe57829003601f168201915b5050505050905090565b600033610df3818585611ff6565b60019150505b92915050565b600a8181548110610cb757600080fd5b600c8181548110610cb757600080fd5b600033610e2d858285612008565b610e38858585612086565b60019150505b9392505050565b60108181548110610cb757600080fd5b610e5d6121d8565b602154610e7a90601790849084906301000000900460ff16612205565b602160036101000a81548160ff021916908360ff1602179055505050565b600060606029548410610ebc57505060408051600080825260208201909252610f99565b6000610ec88486613ea9565b9050602954811115610ed957506029545b610ee38582613ebc565b92508267ffffffffffffffff811115610efe57610efe613e7d565b604051908082528060200260200182016040528015610f27578160200160208202803683370190505b509150845b83811015610f965760276000610f428389613ea9565b815260200190815260200160002060009054906101000a90046001600160a01b0316838281518110610f7657610f76613ecf565b6001600160a01b0390921660209283029190910190910152600101610f2c565b50505b9250929050565b610fa86137ee565b6001600160a01b0383166000908152602b60209081526040808320858452909152908190209051637c3b3b8760e01b81528154600482015260019091015460248201523090637c3b3b879060440161034060405180830381865afa158015611014573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e3e9190613f0f565b604051637c3b3b8760e01b81528135600482015260208201356024820152606090610df9903090637c3b3b87906044015b61034060405180830381865afa158015611087573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906110ab9190613f0f565b612265565b6110b86121d8565b6021546110d590601e9084908490600160501b900460ff16612205565b6021600a6101000a81548160ff021916908360ff1602179055505050565b60088181548110610cb757600080fd5b60098181548110610cb757600080fd5b60128181548110610cb757600080fd5b61112b6121d8565b60215461114b90601a90849084906601000000000000900460ff16612205565b602160066101000a81548160ff021916908360ff1602179055505050565b6111716121d8565b602355565b600061118c6024546001600160a01b0316151590565b6111ad5761119c6009600a614127565b6111a8906103e8614136565b905090565b60006127106001602554426111c29190613ebc565b6111ce6009600a614127565b6111da906103e8614136565b6111e49190614136565b6111ee9190614136565b6111f89190614163565b6127106112076009600a614127565b611213906103e8614136565b61121e906005614136565b6112289190614163565b6112329190613ea9565b90506112406009600a614127565b61124c906103e8614136565b81111561126e5761125f6009600a614127565b61126b906103e8614136565b90505b919050565b61127b6121d8565b61128560006124a3565b565b61128f6121d8565b6021546112ae906019908490849065010000000000900460ff16612205565b602160056101000a81548160ff021916908360ff1602179055505050565b6112d46121d8565b6021546112f590601b9084908490670100000000000000900460ff16612205565b602160076101000a81548160ff021916908360ff1602179055505050565b600d8181548110610cb757600080fd5b6001600160a01b0383166000908152602c6020526040812054606090808510611382576040805160008082526020820190925281611377565b6113646137ee565b81526020019060019003908161135c5790505b5092509250506114d7565b600061138e8587613ea9565b90508181111561139b5750805b6113a58682613ebc565b93508367ffffffffffffffff8111156113c0576113c0613e7d565b6040519080825280602002602001820160405280156113f957816020015b6113e66137ee565b8152602001906001900390816113de5790505b50925060005b848110156114d3576001600160a01b0388166000908152602b602052604081203091637c3b3b879190611432858c613ea9565b81526020019081526020016000206040518263ffffffff1660e01b815260040161146c919081548152600190910154602082015260400190565b61034060405180830381865afa15801561148a573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114ae9190613f0f565b8482815181106114c0576114c0613ecf565b60209081029190910101526001016113ff565b5050505b935093915050565b60068181548110610cb757600080fd5b6114f76137ee565b60006040518060400160405280848036038101906115159190614177565b8152602001600081525090506115296137ee565b600654611535836124f5565b61153f91906141c6565b81526021546115599060ff16611554846124f5565b61254b565b6020820152611580600761156c846124f5565b84516020015161157b90612562565b612584565b604082015260235461159490600390614163565b61159d83612594565b11156115d4576021546115bb90610100900460ff16611554846124f5565b60608201526115ce601061156c846124f5565b60808201525b6021546115ed9062010000900460ff16611554846124f5565b60a0820152600a546115fe836124f5565b61160891906141c6565b60c082015260235461161c90600390614163565b61162583612594565b111561165f57602154611645906301000000900460ff16611554846124f5565b60e0820152611658600b61156c846124f5565b6101008201525b600360235461166e9190614163565b61167783612594565b11156116b35760215461169890640100000000900460ff16611554846124f5565b6101208201526116ac600c61156c846124f5565b6101408201525b60036023546116c29190614163565b6116cb83612594565b1115611708576021546116ed9065010000000000900460ff16611554846124f5565b610160820152611701600961156c846124f5565b6101808201525b60036023546117179190614163565b61172083612594565b111561175e57602154611743906601000000000000900460ff16611554846124f5565b6101a0820152611757600861156c846124f5565b6101c08201525b61176c601161156c846124f5565b6101e082015260215461178c90600160401b900460ff16611554846124f5565b6102008201526117a0600d61156c846124f5565b6102208201526023546117b590600390614163565b6117be83612594565b11156117f9576021546117de90600160481b900460ff16611554846124f5565b6102408201526117f2600e61156c846124f5565b6102608201525b60036023546118089190614163565b61181183612594565b111561184c5760215461183190600160501b900460ff16611554846124f5565b610280820152611845601261156c846124f5565b6102a08201525b600360235461185b9190614163565b61186483612594565b111561189f5760215461188490600160581b900460ff16611554846124f5565b6102c0820152611898600f61156c846124f5565b6102e08201525b60036023546118ae9190614163565b6118b783612594565b1115610e3e576021546118d790600160601b900460ff16611554846124f5565b6103008201526118eb601361156c846124f5565b6103208201529392505050565b60118181548110610cb757600080fd5b600e8181548110610cb757600080fd5b606060048054610d6290613e49565b61192f6121d8565b60215461194b906016908490849062010000900460ff16612205565b602160026101000a81548160ff021916908360ff1602179055505050565b6001600160a01b0383166000908152602c60205260408120546060908085106119d3576040805160008082526020820190925281611377565b60408051808201909152600080825260208201528152602001906001900390816119a25790505092509250506114d7565b60006119df8587613ea9565b9050818111156119ec5750805b6119f68682613ebc565b93508367ffffffffffffffff811115611a1157611a11613e7d565b604051908082528060200260200182016040528015611a5657816020015b6040805180820190915260008082526020820152815260200190600190039081611a2f5790505b50925060005b848110156114d3576001600160a01b0388166000908152602b6020526040812090611a87838a613ea9565b815260200190815260200160002060405180604001604052908160008201548152602001600182015481525050848281518110611ac657611ac6613ecf565b6020908102919091010152600101611a5c565b611ae16121d8565b602154611afc9060159084908490610100900460ff16612205565b602160016101000a81548160ff021916908360ff1602179055505050565b611b226121d8565b602154611b3f9060209084908490600160601b900460ff16612205565b6021600c6101000a81548160ff021916908360ff1602179055505050565b611b656121d8565b602154611b8290601c9084908490600160401b900460ff16612205565b602160086101000a81548160ff021916908360ff1602179055505050565b611ba86121d8565b602154611bc69060189084908490640100000000900460ff16612205565b602160046101000a81548160ff021916908360ff1602179055505050565b600033610df3818585612086565b60138181548110610cb757600080fd5b611c0a6121d8565b602255565b336000908152602c60205260409020548210611c5f5760405162461bcd60e51b815260206004820152600f60248201526e0d2dcc6dee4e4cac6e840d2dcc8caf608b1b604482015260640161046b565b611c6a3383836125b0565b5050565b604051633fc0fdcb60e01b81526001600160a01b038316600482015260248101829052606090610e3e903090633fc0fdcb90604401611069565b611cb06121d8565b602154611ccd90601d9084908490600160481b900460ff16612205565b602160096101000a81548160ff021916908360ff1602179055505050565b600080805b85811015611d215783611d038183614136565b611d0d9190613ea9565b611d179083613ea9565b9150600101611cf0565b611d2b82866141c6565b945060009150600090505b85811015611d775783611d498183614136565b611d539190613ea9565b611d5d9083613ea9565b9150848210611d6f579150610e3e9050565b600101611d36565b50600095945050505050565b6001600160a01b0383166000908152602c6020526040812054606090808510611ddb576040805160008082526020820190925281611377565b6060815260200190600190039081611dbc5790505092509250506114d7565b6000611de78587613ea9565b905081811115611e00575080611dfd8187613ebc565b93505b8367ffffffffffffffff811115611e1957611e19613e7d565b604051908082528060200260200182016040528015611e4c57816020015b6060815260200190600190039081611e375790505b5092508560005b82821015611ee5576001600160a01b0389166000908152602b60209081526040808320858452909152908190209051637c3b3b8760e01b8152815460048201526001909101546024820152611eb2903090637c3b3b8790604401611069565b8582611ebd816141da565b935081518110611ecf57611ecf613ecf565b6020026020010181905250816001019150611e53565b50505050935093915050565b611ef96121d8565b602480546001600160a01b0319166001600160a01b039290921691909117905542602555565b600f8181548110610cb757600080fd5b611f376121d8565b602154611f4d906014908490849060ff16612205565b6021805460ff191660ff929092169190911790555050565b611f6d6121d8565b6001600160a01b038116611f9757604051631e4fbdf760e01b81526000600482015260240161046b565b611fa0816124a3565b50565b600b8181548110610cb757600080fd5b611fbb6121d8565b602154611fd890601f9084908490600160581b900460ff16612205565b6021600b6101000a81548160ff021916908360ff1602179055505050565b6120038383836001612612565b505050565b6001600160a01b038381166000908152600160209081526040808320938616835292905220546000198114612080578181101561207157604051637dc7a0d960e11b81526001600160a01b0384166004820152602481018290526044810183905260640161046b565b61208084848484036000612612565b50505050565b6001600160a01b03821615806120a657506001600160a01b03821661dead145b156120b6576120038383836126e7565b6024546001600160a01b031615801561216057506001600160a01b03831615806120e857506001600160a01b03831630145b8061212457507f00000000000000000000000080c03e5904ed45ab34d6c14daee6c96bf3ec81446001600160a01b0316836001600160a01b0316145b8061216057507f00000000000000000000000080c03e5904ed45ab34d6c14daee6c96bf3ec81446001600160a01b0316826001600160a01b0316145b156121705761200383838361292b565b602454600160a01b900460ff161561218d5761200383838361292b565b6024546001600160a01b03908116908416036121ad57612003828261298a565b6024546001600160a01b03908116908316036121cd576120038382612a5d565b6120038383836126e7565b6005546001600160a01b031633146112855760405163118cdaa760e01b815233600482015260240161046b565b600082810361221557508061225d565b60005b838110156122585761224e8686868481811061223657612236613ecf565b905060200281019061224891906141f3565b85612b7a565b9250600101612218565b829150505b949350505050565b60606000612273600a612c4a565b61227d600a612c4a565b60405160200161228e929190614213565b60408051601f1981840301815291905290506000816122ad600a612c4a565b6122b7600a612c4a565b60068760000151815481106122ce576122ce613ecf565b906000526020600020016040516020016122ea939291906142ae565b60405160208183030381529060405261230f6014600788602001518960400151612d4b565b6123256016600a8960a001518a60c00151612d4b565b61233b601560108a606001518b60800151612d4b565b6123526017600b8b60e001518c6101000151612d4b565b61236a6018600c8c61012001518d6101400151612d4b565b612382601960098d61016001518e6101800151612d4b565b61239a601a60088e6101a001518f6101c00151612d4b565b6040516020016123b2999897969594939291906143be565b604051602081830303815290604052905060006123d9601b60116001886101e00151612d4b565b6123f1601c600d886102000151896102200151612d4b565b612409601d600e8961024001518a6102600151612d4b565b612421601e60128a61028001518b6102a00151612d4b565b612439602060138b61030001518c6103200151612d4b565b612451601f600f8c6102c001518d6102e00151612e47565b6040516020016124669695949392919061447f565b6040516020818303038152906040529050818160405160200161248a9291906144fe565b6040516020818303038152906040529350505050919050565b600580546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80518051602091820151918301805160009391612511826141da565b9052604080516020810194909452830191909152606082015260800160408051601f19818403018152919052805160209091012092915050565b600061255783836141c6565b610e3e906001613ea9565b600060225482101561257c5781602254610df99190613ebc565b506001919050565b825460009061225d908484611ceb565b8051602001516000906125a6836124f5565b610df991906141c6565b6001600160a01b0383166000908152602b6020908152604080832085845282529182902082518084019093528054835260010154908201526125fe84836125f96009600a614127565b612e99565b6126088484612efd565b6120808282613007565b6001600160a01b03841661263c5760405163e602df0560e01b81526000600482015260240161046b565b6001600160a01b03831661266657604051634a1406b160e11b81526000600482015260240161046b565b6001600160a01b038085166000908152600160209081526040808320938716835292905220829055801561208057826001600160a01b0316846001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925846040516126d991815260200190565b60405180910390a350505050565b6126ef6130cc565b6001600160a01b038316600090815260208190526040812054906127138383613ebc565b90506000612736856001600160a01b031660009081526020819052604090205490565b905060006127448583613ea9565b90506001600160a01b038616158061276657506001600160a01b03861661dead145b15612772575060009050805b60006127806009600a614127565b61278a9085614163565b6127966009600a614127565b6127a09087614163565b6127aa9190613ebc565b905060006127ba6009600a614127565b6127c49085614163565b6127d06009600a614127565b6127da9085614163565b6127e49190613ebc565b905081818111156127f25750805b6001600160a01b038a166000908152602c60205260408120545b828210156128845780156128845760006128258261453e565b6001600160a01b038e166000908152602b60209081526040808320848452825291829020825180840190935280548352600101549082015290925082915061286d8e83612efd565b6128778d82613007565b505081600101915061280c565b82915b858310156128b557600061289a8361453e565b92508290506128a98e82612efd565b50826001019250612887565b8092505b8483101561290c5760006040518060400160405280602e600081546128dd906141da565b918290555081526020016128f26103e86130f6565b905290506129008d82613007565b508260010192506128b9565b6129178d8d8d612e99565b505050505050505050506120036001602655565b6001600160a01b03831661295557604051634b637e8f60e11b81526000600482015260240161046b565b6001600160a01b03821661297f5760405163ec442f0560e01b81526000600482015260240161046b565b612003838383613145565b6129926130cc565b6001600160a01b038216600090815260208190526040812054906129b68383613ea9565b905060006129c66009600a614127565b6129d09084614163565b6129dc6009600a614127565b6129e69084614163565b6129f09190613ebc565b905060005b81811015612a455760006040518060400160405280602e60008154612a19906141da565b91829055508152602001612a2e6103e86130f6565b90529050612a3c8782613007565b506001016129f5565b612a4f868661326f565b50505050611c6a6001602655565b6024805460ff60a01b1916600160a01b179055612a786130cc565b6001600160a01b03821660009081526020819052604081205490612a9c8383613ebc565b90506000612aac6009600a614127565b612ab69083614163565b612ac26009600a614127565b612acc9085614163565b612ad69190613ebc565b6001600160a01b0386166000908152602c6020526040812054919250905b82821015612b42576103e8602a541015612b1c57602a60008154612b17906141da565b909155505b8015612b3757612b3787612b2f8361453e565b925082612efd565b816001019150612af4565b602454612b5a9088906001600160a01b031688612086565b5050505050612b696001602655565b50506024805460ff60a01b19169055565b81356000908152602084905260408120805415612bbf57846000612ba060018735613ebc565b81526020019081526020016000206000612bba91906138b1565b612bcb565b612bc883614555565b92505b60005b612bdb6020860186614574565b9050811015612c405781612bf26020870187614574565b83818110612c0257612c02613ecf565b9050602002810190612c1491906141f3565b815460018101835560009283526020909220909160020201612c368282614716565b5050600101612bce565b5091949350505050565b606081600003612c715750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612c9b5780612c85816141da565b9150612c949050600a83614163565b9150612c75565b60008167ffffffffffffffff811115612cb657612cb6613e7d565b6040519080825280601f01601f191660200182016040528015612ce0576020820181803683370190505b5090505b841561225d57612cf5600183613ebc565b9150612d02600a866141c6565b612d0d906030613ea9565b60f81b818381518110612d2257612d22613ecf565b60200101906001600160f81b031916908160001a905350612d44600a86614163565b9450612ce4565b606082600003612d6a575060408051602081019091526000815261225d565b612e3e848381548110612d7f57612d7f613ecf565b906000526020600020018054612d9490613e49565b80601f0160208091040260200160405190810160405280929190818152602001828054612dc090613e49565b8015612e0d5780601f10612de257610100808354040283529160200191612e0d565b820191906000526020600020905b815481529060010190602001808311612df057829003601f168201915b5050505050866000600187612e229190613ebc565b81526020019081526020016000206132da90919063ffffffff16565b95945050505050565b606082600003612e66575060408051602081019091526000815261225d565b82600103612d6a57612e92856000612e7f600187613ebc565b815260200190815260200160002061347e565b905061225d565b6024805460ff60a01b1916600160a01b1790556001600160a01b0382161580612ecc57506001600160a01b03821661dead145b15612ee057612edb8382613617565b612eeb565b612eeb83838361292b565b50506024805460ff60a01b1916905550565b6024546001600160a01b0390811690831603612f17575050565b6001600160a01b0382166000908152602c602052604081208054909190612f3d9061453e565b9182905550600003612f5257612f528261364d565b602d60008154612f619061453e565b909155506001600160a01b0382166000908152602c6020526040902054818114612fd5576001600160a01b0383166000908152602b60209081526040808320848452808352818420825180840184528154815260019182015481860190815288875292909452919093209151825591519101555b6001600160a01b039092166000908152602b602090815260408083209483529390529182208281556001019190915550565b6024546001600160a01b0390811690831603613021575050565b6001600160a01b0382166000908152602c602052604081208054909190613047906141da565b918290555060010361305c5761305c82613734565b602d6000815461306b906141da565b909155506001600160a01b0382166000908152602c602052604081205461309490600190613ebc565b6001600160a01b03939093166000908152602b6020908152604080832095835294815293902082518155919092015160019091015550565b6002602654036130ef57604051633ee5aeb560e01b815260040160405180910390fd5b6002602655565b60006103e8602a54836131099190614136565b6131139190614163565b91508160000361312257600191505b6001602a54111561314157602a6000815461313c9061453e565b909155505b5090565b6001600160a01b0383166131705780600260008282546131659190613ea9565b909155506131e29050565b6001600160a01b038316600090815260208190526040902054818110156131c35760405163391434e360e21b81526001600160a01b0385166004820152602481018290526044810183905260640161046b565b6001600160a01b03841660009081526020819052604090209082900390555b6001600160a01b0382166131fe5760028054829003905561321d565b6001600160a01b03821660009081526020819052604090208054820190555b816001600160a01b0316836001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef8360405161326291815260200190565b60405180910390a3505050565b80613278611176565b8111156132b15760405162461bcd60e51b81526020600482015260076024820152666d61782062757960c81b604482015260640161046b565b6024805460ff60a01b198116600160a01b17909155612eeb906001600160a01b0316848461292b565b60608060005b8454811015613476578161344b8587848154811061330057613300613ecf565b906000526020600020906002020160405180604001604052908160008201805461332990613e49565b80601f016020809104026020016040519081016040528092919081815260200182805461335590613e49565b80156133a25780601f10613377576101008083540402835291602001916133a2565b820191906000526020600020905b81548152906001019060200180831161338557829003601f168201915b505050505081526020016001820180546133bb90613e49565b80601f01602080910402602001604051908101604052809291908181526020018280546133e790613e49565b80156134345780601f1061340957610100808354040283529160200191613434565b820191906000526020600020905b81548152906001019060200180831161341757829003601f168201915b50505050508152505061378990919063ffffffff16565b60405160200161345c9291906147f9565b60408051601f1981840301815291905291506001016132e0565b509392505050565b60608060005b835481101561361057816135e58583815481106134a3576134a3613ecf565b90600052602060002090600202016040518060400160405290816000820180546134cc90613e49565b80601f01602080910402602001604051908101604052809291908181526020018280546134f890613e49565b80156135455780601f1061351a57610100808354040283529160200191613545565b820191906000526020600020905b81548152906001019060200180831161352857829003601f168201915b5050505050815260200160018201805461355e90613e49565b80601f016020809104026020016040519081016040528092919081815260200182805461358a90613e49565b80156135d75780601f106135ac576101008083540402835291602001916135d7565b820191906000526020600020905b8154815290600101906020018083116135ba57829003601f168201915b5050505050815250506137bb565b6040516020016135f69291906147f9565b60408051601f198184030181529190529150600101613484565b5092915050565b6001600160a01b03821661364157604051634b637e8f60e11b81526000600482015260240161046b565b611c6a82600083613145565b60295460000361365a5750565b6001600160a01b03811660009081526028602052604090205460295461368290600190613ebc565b81146136e757600060276000600160295461369d9190613ebc565b815260208082019290925260409081016000908120548582526027845282822080546001600160a01b0319166001600160a01b039092169182179055815260289092529020829055505b6029600081546136f69061453e565b90915550506001600160a01b0316600090815260286020908152604080832083905560295483526027909152902080546001600160a01b0319169055565b6029805460009182613745836141da565b90915550600081815260276020908152604080832080546001600160a01b039097166001600160a01b03199097168717905594825260289052929092209190915550565b6060818360200151836040516020016137a493929190614828565b604051602081830303815290604052905092915050565b6060816000015182602001516040516020016137d89291906148a7565b6040516020818303038152906040529050919050565b60405180610340016040528060008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b5080546000825560020290600052602060002090810190611fa091905b808211156131415760006138e282826138f9565b6138f06001830160006138f9565b506002016138ce565b50805461390590613e49565b6000825580601f10613915575050565b601f016020900490600052602060002090810190611fa091905b80821115613141576000815560010161392f565b80356001600160a01b038116811461126e57600080fd5b60006020828403121561396c57600080fd5b610e3e82613943565b60006020828403121561398757600080fd5b5035919050565b60005b838110156139a9578181015183820152602001613991565b50506000910152565b600081518084526139ca81602086016020860161398e565b601f01601f19169290920160200192915050565b602081526000610e3e60208301846139b2565b60008060408385031215613a0457600080fd5b613a0d83613943565b946020939093013593505050565b600080600060608486031215613a3057600080fd5b613a3984613943565b9250613a4760208501613943565b9150604084013590509250925092565b60008060208385031215613a6a57600080fd5b823567ffffffffffffffff80821115613a8257600080fd5b818501915085601f830112613a9657600080fd5b813581811115613aa557600080fd5b8660208260051b8501011115613aba57600080fd5b60209290920196919550909350505050565b60008060408385031215613adf57600080fd5b50508035926020909101359150565b60006040820184835260206040602085015281855180845260608601915060208701935060005b81811015613b3a5784516001600160a01b031683529383019391830191600101613b15565b5090979650505050505050565b805182526020808201519083015260408082015190830152606080820151908301526080808201519083015260a0808201519083015260c0808201519083015260e08082015190830152610100808201519083015261012080820151908301526101408082015190830152610160808201519083015261018080820151908301526101a080820151908301526101c080820151908301526101e08082015190830152610200808201519083015261022080820151908301526102408082015190830152610260808201519083015261028080820151908301526102a080820151908301526102c080820151908301526102e08082015190830152610300808201519083015261032090810151910152565b6103408101610df98284613b47565b600060408284031215613c7957600080fd5b50919050565b600080600060608486031215613c9457600080fd5b613c9d84613943565b95602085013595506040909401359392505050565b60006040820184835260206040602085015281855180845260608601915060208701935060005b81811015613b3a57613cec838651613b47565b938301936103409290920191600101613cd9565b6000604080830185845260206040602086015281865180845260608701915060208801935060005b81811015613d4d57845180518452840151848401529383019391850191600101613d28565b509098975050505050505050565b60008060408385031215613d6e57600080fd5b82359150613d7e60208401613943565b90509250929050565b600080600060608486031215613d9c57600080fd5b505081359360208301359350604090920135919050565b60006040820184835260206040602085015281855180845260608601915060608160051b87010193506020870160005b82811015613e1157605f19888703018452613dff8683516139b2565b95509284019290840190600101613de3565b509398975050505050505050565b60008060408385031215613e3257600080fd5b613e3b83613943565b9150613d7e60208401613943565b600181811c90821680613e5d57607f821691505b602082108103613c7957634e487b7160e01b600052602260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b634e487b7160e01b600052601160045260246000fd5b80820180821115610df957610df9613e93565b81810381811115610df957610df9613e93565b634e487b7160e01b600052603260045260246000fd5b604051610340810167ffffffffffffffff81118282101715613f0957613f09613e7d565b60405290565b60006103408284031215613f2257600080fd5b613f2a613ee5565b825181526020808401519082015260408084015190820152606080840151908201526080808401519082015260a0808401519082015260c0808401519082015260e08084015190820152610100808401519082015261012080840151908201526101408084015190820152610160808401519082015261018080840151908201526101a080840151908201526101c080840151908201526101e08084015190820152610200808401519082015261022080840151908201526102408084015190820152610260808401519082015261028080840151908201526102a080840151908201526102c080840151908201526102e080840151908201526103008084015190820152610320928301519281019290925250919050565b600181815b8085111561407e57816000190482111561406457614064613e93565b8085161561407157918102915b93841c9390800290614048565b509250929050565b60008261409557506001610df9565b816140a257506000610df9565b81600181146140b857600281146140c2576140de565b6001915050610df9565b60ff8411156140d3576140d3613e93565b50506001821b610df9565b5060208310610133831016604e8410600b8410161715614101575081810a610df9565b61410b8383614043565b806000190482111561411f5761411f613e93565b029392505050565b6000610e3e60ff841683614086565b8082028115828204841417610df957610df9613e93565b634e487b7160e01b600052601260045260246000fd5b6000826141725761417261414d565b500490565b60006040828403121561418957600080fd5b6040516040810181811067ffffffffffffffff821117156141ac576141ac613e7d565b604052823581526020928301359281019290925250919050565b6000826141d5576141d561414d565b500690565b6000600182016141ec576141ec613e93565b5060010190565b60008235603e1983360301811261420957600080fd5b9190910192915050565b7f3c73766720786d6c6e733d27687474703a2f2f7777772e77332e6f72672f3230815273030302f737667272076696577426f783d273020360641b60208201526000600160fd1b806034840152845161427381603586016020890161398e565b80840190508160358201528451915061429382603683016020880161398e565b61139f60f11b91016036810191909152603801949350505050565b703c7265637420783d27302720793d27302760781b8152672077696474683d2760c01b60118201526000845160206142ed826019860160208a0161398e565b6927206865696768743d2760b01b6019928501928301528551614317816023850160208a0161398e565b80830192505067272066696c6c3d2760c01b6023830152602b6000865461433d81613e49565b600182811680156143555760018114614370576143a2565b60ff198416602b890152602b831515840289010194506143a2565b8a600052602060002060005b848110156143975781548a820189015290830190880161437c565b5050602b8389010194505b50506213979f60e91b8352505060030198975050505050505050565b60008a516143d0818460208f0161398e565b8a516143e28183860160208f0161398e565b8a5191840101906143f7818360208e0161398e565b89516144098183850160208e0161398e565b895192909101019061441f818360208c0161398e565b87516144318183850160208c0161398e565b8751929091010190614447818360208a0161398e565b85516144598183850160208a0161398e565b855192909101019061446f81836020880161398e565b019b9a5050505050505050505050565b6000875160206144928285838d0161398e565b8851918401916144a58184848d0161398e565b88519201916144b78184848c0161398e565b87519201916144c98184848b0161398e565b86519201916144db8184848a0161398e565b85519201916144ed818484890161398e565b919091019998505050505050505050565b6000835161451081846020880161398e565b83519083019061452481836020880161398e565b651e17b9bb339f60d11b9101908152600601949350505050565b60008161454d5761454d613e93565b506000190190565b600060ff821660ff810361456b5761456b613e93565b60010192915050565b6000808335601e1984360301811261458b57600080fd5b83018035915067ffffffffffffffff8211156145a657600080fd5b6020019150600581901b3603821315610f9957600080fd5b6000808335601e198436030181126145d557600080fd5b83018035915067ffffffffffffffff8211156145f057600080fd5b602001915036819003821315610f9957600080fd5b601f821115612003576000816000526020600020601f850160051c8101602086101561462e5750805b601f850160051c820191505b8181101561464d5782815560010161463a565b505050505050565b67ffffffffffffffff83111561466d5761466d613e7d565b6146818361467b8354613e49565b83614605565b6000601f8411600181146146b5576000851561469d5750838201355b600019600387901b1c1916600186901b17835561470f565b600083815260209020601f19861690835b828110156146e657868501358255602094850194600190920191016146c6565b50868210156147035760001960f88860031b161c19848701351681555b505060018560011b0183555b5050505050565b61472082836145be565b67ffffffffffffffff81111561473857614738613e7d565b61474c816147468554613e49565b85614605565b6000601f82116001811461478057600083156147685750838201355b600019600385901b1c1916600184901b1785556147da565b600085815260209020601f19841690835b828110156147b15786850135825560209485019460019092019101614791565b50848210156147ce5760001960f88660031b161c19848701351681555b505060018360011b0185555b505050506147eb60208301836145be565b612080818360018601614655565b6000835161480b81846020880161398e565b83519083019061481f81836020880161398e565b01949350505050565b6b3c706174682066696c6c3d2760a01b81526000845161484f81600c85016020890161398e565b642720643d2760d81b600c91840191820152845161487481601184016020890161398e565b845191019061488a81601184016020880161398e565b6213979f60e91b6011929091019182015260140195945050505050565b6b3c706174682066696c6c3d2760a01b8152600083516148ce81600c85016020880161398e565b642720643d2760d81b600c9184019182015283516148f381601184016020880161398e565b6213979f60e91b6011929091019182015260140194935050505056fea2646970667358221220899f393b6cf7d8ceaa63105592e572691d18892b3a0ae9bcac147673f25286cf64736f6c63430008190033
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.