Token
MicroBuddies (MBDY)
ERC-721
Overview
Max Total Supply
29,759 MBDY
Holders
226
Market
Onchain Market Cap
$0.00
Circulating Supply Market Cap
-
Other Info
Token Contract
Balance
400 MBDYLoading...
Loading
Loading...
Loading
Loading...
Loading
Contract Name:
BuddyCore
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 800 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; // | \/ (_) | _ \ | | | (_) // | \ / |_ ___ _ __ ___ | |_) |_ _ __| | __| |_ ___ ___ ™ // | |\/| | |/ __| '__/ _ \| _ <| | | |/ _` |/ _` | |/ _ \/ __| // | | | | | (__| | | (_) | |_) | |_| | (_| | (_| | | __/\__ \ // |_| |_|_|\___|_| \___/|____/ \__,_|\__,_|\__,_|_|\___||___/ 2021 import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC721/utils/ERC721Holder.sol"; import "./ERC721Full.sol"; import "./libraries/BuddyLib.sol"; import "./interfaces/IBuddyCore.sol"; import "./interfaces/IGoo.sol"; import "./interfaces/IBuddyLogic.sol"; contract BuddyCore is IBuddyCore, ERC721Full, ERC721Holder { IERC20 public _nanoFactoryToken; IGoo public _goo; IBuddyLogic public _buddyLogic; uint256 public lastFounderClaim; uint256 public lastFounderClaimTime; uint256 public constant blackHole = 1; /*** EVENTS ***/ event Birth( uint256 indexed tokenId, address indexed owner, uint256 indexed dna ); constructor( address _gooAddr, address _nanoFactoryAddr, address _buddyLogicAddr ) { _goo = IGoo(_gooAddr); _nanoFactoryToken = IERC20(_nanoFactoryAddr); _buddyLogic = IBuddyLogic(_buddyLogicAddr); lastFounderClaimTime = block.timestamp; } modifier onlyHolder(uint256 _tokenId) { require(msg.sender == ownerOf(_tokenId), "Unauthorized"); _; } function setGooContract(address _gooContractAddr) external onlyOwner { _goo = IGoo(_gooContractAddr); } function setNanoContract(address _nanoContractAddr) external onlyOwner { _nanoFactoryToken = IERC20(_nanoContractAddr); } function setLogicContract(address _logicContractAddr) external onlyOwner { _buddyLogic = IBuddyLogic(_logicContractAddr); } function getBlackHole() external pure override returns (uint256) { return blackHole; } function getApproval(uint256 tokenId) public view override returns (address) { return super.getApproved(tokenId); } function getOwnerOf(uint256 tokenId) public view override returns (address) { return super.ownerOf(tokenId); } function getBuddy(uint256 _tokenId) public view returns ( uint8, uint8, uint8, uint8, uint24, uint256, uint256, uint256, uint256, uint256 ) { BuddyLib.Buddy storage base = _data[_tokenId]; return ( base.species, base.repMax, base.repCur, base.special, base.gen, base.dna, base.birth, base.totalProduced, base.lastRewardTime, base.parent ); } function generateBlackHole(address addr) external onlyOwner { BuddyLib.Buddy memory bh = BuddyLib.generate(0); bh.special = 1; uint256 tokenId = safeMint(addr); _data[tokenId] = bh; emit Birth(tokenId, addr, bh.dna); } function buyGen0() external whenNotPaused { uint256 nanoBalance = _nanoFactoryToken.balanceOf(msg.sender); require(nanoBalance >= 1e18, "you need nano to buy gen0"); uint256 nanoAllowance = _nanoFactoryToken.allowance( msg.sender, address(this) ); require(nanoAllowance >= 1e18, "you need nano allowance "); require( getTokenId() > 11 || msg.sender == owner(), "You must wait for founders" ); _nanoFactoryToken.transferFrom( msg.sender, address(0x000000000000000000000000000000000000dEaD), 1e18 ); uint256 tokenId = safeMint(msg.sender); uint256 dna = _buddyLogic.createGen0(tokenId); BuddyLib.Buddy memory base = BuddyLib.generate(dna); if (tokenId <= 11) { base.special = 2; } _data[tokenId] = base; _goo.mint(tokenId, _buddyLogic.getStartingGoo() * 1e18); emit Birth(tokenId, msg.sender, base.dna); } function replicate( uint256 _tokenId, int8[6] calldata dominantLock, int8[24] calldata recessiveSwap, bool useAllBuddies ) external onlyHolder(_tokenId) whenNotPaused { uint256 cost = replicatePreview(_tokenId, dominantLock, recessiveSwap); uint256[] memory buddies; uint256 gooBalance = _goo.balanceOf(_tokenId); if (useAllBuddies) { buddies = getTokensByOwner(); for (uint256 i = 0; i < buddies.length; i++) { if (buddies[i] == _tokenId) { continue; } gooBalance += _goo.balanceOf(buddies[i]); } } require(gooBalance >= cost, "You do not have enough GOO"); uint256 gooAllowance = _goo.allowance(_tokenId, blackHole); require(gooAllowance >= cost, "you need goo allowance"); uint256 newCost = cost; if (useAllBuddies) { uint256 ogBalance = _goo.balanceOf(_tokenId); if (ogBalance < newCost) { newCost -= ogBalance; for (uint256 i = 0; i < buddies.length; i++) { if (buddies[i] == _tokenId) { continue; } uint256 id = buddies[i]; uint256 balance = _goo.balanceOf(id); if (balance < newCost) { _goo.transferFrom(blackHole, id, blackHole, balance); newCost -= balance; } else { _goo.transferFrom(blackHole, id, blackHole, newCost); newCost = 0; break; } } newCost += ogBalance; } } _goo.transferFrom(blackHole, _tokenId, blackHole, newCost); _goo.burn(blackHole, (cost * _buddyLogic.getBurnPercent()) / 100); BuddyLib.Buddy storage base = _data[_tokenId]; base.repCur += 1; uint256 dna = _buddyLogic.repBuddy(base, dominantLock, recessiveSwap); BuddyLib.Buddy memory child = BuddyLib.generate(dna); child.parent = _tokenId; child.repMax = _buddyLogic.calcReps(child.gen); _buddyLogic.getRandom(); child.dna = dna; uint256 tokenId = safeMint(msg.sender); _data[tokenId] = child; emit Birth(tokenId, msg.sender, child.dna); } function replicatePreview( uint256 _tokenId, int8[6] memory dominantLock, int8[24] memory recessiveSwap ) public view returns (uint256) { BuddyLib.Buddy storage base = _data[_tokenId]; require(base.special == 0, "Specials cannot Replicate"); require(base.repCur < base.repMax, "Buddy is barren"); require(base.gen < _buddyLogic.getMaxGen(), "MAX GENERATION"); uint256 grossGPD = calcGGPD(_tokenId, false, true); return _buddyLogic.replicatePreview(dominantLock, recessiveSwap, grossGPD); } function simpleReplicate(uint256 _tokenId) external onlyHolder(_tokenId) whenNotPaused { uint256 cost = simpleReplicatePreview(_tokenId); uint256 gooBalance = _goo.balanceOf(_tokenId); require(gooBalance >= cost, "you need goo to replicate"); uint256 gooAllowance = _goo.allowance(_tokenId, blackHole); require(gooAllowance >= cost, "you need goo allowance"); _goo.transferFrom(blackHole, _tokenId, blackHole, cost); _goo.burn(blackHole, (cost * _buddyLogic.getBurnPercent()) / 100); BuddyLib.Buddy storage base = _data[_tokenId]; base.repCur += 1; uint256 dna = _buddyLogic.simpleRepBuddy(base); BuddyLib.Buddy memory child = BuddyLib.generate(dna); child.parent = _tokenId; child.repMax = _buddyLogic.calcReps(child.gen); _buddyLogic.getRandom(); child.dna = dna; uint256 tokenId = safeMint(msg.sender); _data[tokenId] = child; emit Birth(tokenId, msg.sender, child.dna); } function simpleReplicatePreview(uint256 _tokenId) public view returns (uint256) { BuddyLib.Buddy storage base = _data[_tokenId]; require(base.special == 0, "Specials cannot Replicate"); require(base.repCur < base.repMax, "Buddy is barren"); require(base.gen < _buddyLogic.getMaxGen(), "MAX GENERATION"); uint256 grossGPD = calcGGPD(_tokenId, false, false); return _buddyLogic.simpleReplicatePreview(grossGPD); } function calcGGPD( uint256 _tokenId, bool fertility, bool recessiveBonus ) public view returns (uint256) { BuddyLib.Buddy storage base = _data[_tokenId]; return _buddyLogic.calcGGPD(base, fertility, recessiveBonus); } function getMaxBalance(uint256 _tokenId) public view override returns (uint256) { BuddyLib.Buddy storage base = _data[_tokenId]; uint256 ggpd = (_buddyLogic.calcGGPD(base, false, false)) * 90; return ggpd * 1e18; } function calcPeg() external view returns (uint256) { return _buddyLogic.calcPeg(); } function calcApop(uint256 _tokenId) public view returns (uint256) { BuddyLib.Buddy storage base = _data[_tokenId]; return _buddyLogic.calcApop(base.totalProduced); } function claim(uint256 _tokenId) public onlyHolder(_tokenId) whenNotPaused returns (uint256 total) { BuddyLib.Buddy storage base = _data[_tokenId]; require(base.special == 0, "Specials do not make GOO!"); require( block.timestamp - base.lastRewardTime > 5 minutes, "Claim on cooldown" ); total = calcClaim(_tokenId); base.lastRewardTime = block.timestamp; base.totalProduced += total; _goo.mint(_tokenId, total); } function calcClaim(uint256 _tokenId) public view returns (uint256) { BuddyLib.Buddy storage base = _data[_tokenId]; return _buddyLogic.calcClaim(base); } function getTokensByOwner() public view returns (uint256[] memory tokens) { uint256 tokenCount = balanceOf(msg.sender); if (tokenCount == 0) { return new uint256[](0); } else { uint256[] memory result = new uint256[](tokenCount); for (uint256 i = 0; i < tokenCount; i++) { uint256 tokenId = tokenOfOwnerByIndex(msg.sender, i); result[i] = tokenId; } return result; } } function getBalanceByOwner() external view returns (uint256 balance) { uint256[] memory tokens = getTokensByOwner(); for (uint256 i = 0; i < tokens.length; i++) { balance += _goo.balanceOf(tokens[i]); } } function claimAll(uint256[] memory tokens) external whenNotPaused returns (uint256 total) { for (uint256 i = 0; i < tokens.length; i++) { total += claim(tokens[i]); } } /// @dev Call to destroy a buddy in exchange for % of total produced Goo. function apoptosis(uint256 _tokenId, uint256[] memory receivers) external onlyHolder(_tokenId) whenNotPaused { BuddyLib.Buddy storage base = _data[_tokenId]; require(base.special == 0, "Specials cannot Apop"); require( base.totalProduced > 100, "Buddy must produce at least 100 GOO" ); uint256 amount = calcApop(_tokenId); for (uint256 i = 0; i < receivers.length; i++) { if (receivers[i] == _tokenId) { continue; } uint256 receiver = receivers[i]; uint256 rMax = getMaxBalance(receiver); if (amount > rMax) { _goo.mint(rMax, receiver); amount -= rMax; } else { _goo.mint(amount, receiver); break; } } transferFrom( msg.sender, address(0x000000000000000000000000000000000000dEaD), _tokenId ); } function calcFounderClaim(uint256 _tokenId) public view returns (uint256) { BuddyLib.Buddy storage base = _data[_tokenId]; require(base.special == 2, "Not a Founder"); require( block.timestamp >= base.lastRewardTime + 1 weeks, "you must wait at least 1 week" ); if ( lastFounderClaim == 0 || block.timestamp >= lastFounderClaimTime + 1 weeks ) { uint256 claimedAmount = (_goo.balanceOf(blackHole) * (100 - _buddyLogic.getBurnPercent())) / 100; return claimedAmount; } return lastFounderClaim; } function founderClaim(uint256 _tokenId) public onlyHolder(_tokenId) whenNotPaused { BuddyLib.Buddy storage base = _data[_tokenId]; uint256 claimAmount = calcFounderClaim(_tokenId); uint256 time = block.timestamp; if (time >= lastFounderClaimTime + 1 weeks) { lastFounderClaim = 0; } base.lastRewardTime = time; if (lastFounderClaim == 0) { lastFounderClaim = claimAmount; lastFounderClaimTime = time; } _goo.transfer(blackHole, _tokenId, claimAmount); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval(address indexed owner, address indexed spender, uint256 value); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC721Receiver.sol"; /** * @dev Implementation of the {IERC721Receiver} interface. * * Accepts all token transfers. * Make sure the contract is able to use its token with {IERC721-safeTransferFrom}, {IERC721-approve} or {IERC721-setApprovalForAll}. */ contract ERC721Holder is IERC721Receiver { /** * @dev See {IERC721Receiver-onERC721Received}. * * Always returns `IERC721Receiver.onERC721Received.selector`. */ function onERC721Received( address, address, uint256, bytes memory ) public virtual override returns (bytes4) { return this.onERC721Received.selector; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; // | \/ (_) | _ \ | | | (_) // | \ / |_ ___ _ __ ___ | |_) |_ _ __| | __| |_ ___ ___ ™ // | |\/| | |/ __| '__/ _ \| _ <| | | |/ _` |/ _` | |/ _ \/ __| // | | | | | (__| | | (_) | |_) | |_| | (_| | (_| | | __/\__ \ // |_| |_|_|\___|_| \___/|____/ \__,_|\__,_|\__,_|_|\___||___/ 2021 import "@openzeppelin/contracts/token/ERC721/ERC721.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/ERC721URIStorage.sol"; import "@openzeppelin/contracts/security/Pausable.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/Counters.sol"; import "./libraries/BuddyLib.sol"; import "./interfaces/IMutations.sol"; contract ERC721Full is ERC721, ERC721Enumerable, ERC721URIStorage, Pausable, Ownable { using Counters for Counters.Counter; Counters.Counter private _tokenIdCounter; uint256 private _nonce; /// @dev A mapping to store all buddies. // Buddy[] _data; mapping(uint256 => BuddyLib.Buddy) internal _data; constructor() ERC721("MicroBuddies", "MBDY") {} function safeMint(address to) internal returns (uint256 tokenId) { uint256 current = getTokenId(); _safeMint(to, current); _setTokenURI( current, string(abi.encodePacked(Strings.toString(current), ".json")) ); _tokenIdCounter.increment(); return current; } function getTokenId() internal view returns (uint256 tokenId) { return _tokenIdCounter.current(); } function _baseURI() internal pure override returns (string memory) { return "https://api.microbuddies.io/"; } function pause() public onlyOwner { _pause(); } function unpause() public onlyOwner { _unpause(); } function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal override(ERC721, ERC721Enumerable) whenNotPaused { super._beforeTokenTransfer(from, to, tokenId); } function _burn(uint256 tokenId) internal override(ERC721, ERC721URIStorage) { super._burn(tokenId); } function tokenURI(uint256 tokenId) public view override(ERC721, ERC721URIStorage) returns (string memory) { return super.tokenURI(tokenId); } function supportsInterface(bytes4 interfaceId) public view override(ERC721, ERC721Enumerable) returns (bool) { return super.supportsInterface(interfaceId); } /** * Override isApprovedForAll to auto-approve OS's proxy contract */ function isApprovedForAll(address _owner, address _operator) public view override returns (bool isOperator) { // if OpenSea's ERC721 Proxy Address is detected, auto-return true if (_operator == address(0x58807baD0B376efc12F5AD86aAc70E78ed67deaE)) { return true; } // otherwise, use the default ERC721.isApprovedForAll() return ERC721.isApprovedForAll(_owner, _operator); } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; // | \/ (_) | _ \ | | | (_) // | \ / |_ ___ _ __ ___ | |_) |_ _ __| | __| |_ ___ ___ ™ // | |\/| | |/ __| '__/ _ \| _ <| | | |/ _` |/ _` | |/ _ \/ __| // | | | | | (__| | | (_) | |_) | |_| | (_| | (_| | | __/\__ \ // |_| |_|_|\___|_| \___/|____/ \__,_|\__,_|\__,_|_|\___||___/ 2021 library BuddyLib { //Special - 0 = None - 1 = Blackhole - 2 = Founder struct Buddy { uint8 species; uint8[30] traits; uint8 gen; uint8 repMax; uint8 repCur; uint8 special; uint256 dna; uint256 birth; uint256 totalProduced; uint256 lastRewardTime; uint256 parent; } function generate(uint256 dna) external view returns (Buddy memory base) { uint8[] memory unpack = decode(dna); base.species = unpack[0]; for (uint8 i = 1; i < 31; i++) { base.traits[i - 1] = unpack[i]; } base.birth = block.timestamp; base.totalProduced = 0; base.lastRewardTime = block.timestamp; base.dna = dna; base.gen = unpack[31]; base.repMax = 5; base.repCur = 0; return base; } function decode(uint256 dna) public pure returns (uint8[] memory) { uint8[] memory traits = new uint8[](32); uint256 i; for (i = 0; i < 32; i++) { traits[i] = uint8(sliceNumber(dna, 8, i * 8)); } return traits; } /// @dev given a number get a slice of any bits, at certain offset /// @param _n a number to be sliced /// @param _nbits how many bits long is the new number /// @param _offset how many bits to skip function sliceNumber( uint256 _n, uint256 _nbits, uint256 _offset ) public pure returns (uint256) { // mask is made by shifting left an offset number of times uint256 mask = (pow(2, _nbits) - 1) << _offset; // AND n with mask, and trim to max of _nbits bits return uint256((_n & mask) >> _offset); } function pow(uint256 A, uint256 B) public pure returns (uint256) { return A**B; } function encode(uint8[] memory traits) external pure returns (uint256 dna) { dna = 0; for (uint256 i = 0; i < 32; i++) { dna = dna << 8; // bitwise OR trait with _genes dna = dna | traits[31 - i]; } } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IBuddyCore { function getApproval(uint256) external view returns (address); function getOwnerOf(uint256) external view returns (address); function getBlackHole() external pure returns (uint256); function getMaxBalance(uint256) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; interface IGoo { function balanceOf(uint256 buddy) external view returns (uint256); function mint(uint256 buddy, uint256 amount) external; function burn(uint256 buddy, uint256 amount) external; function allowance(uint256 buddy, uint256 spender) external view returns (uint256); function transfer( uint256 from, uint256 to, uint256 amount ) external returns (bool); function transferFrom( uint256 executor, uint256 from, uint256 to, uint256 amount ) external returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../libraries/BuddyLib.sol"; interface IBuddyLogic { function getMaxGen() external pure returns (uint8); function createGen0(uint256 tokenId) external returns (uint256); function calcClaim(BuddyLib.Buddy calldata base) external view returns (uint256); function calcGGPD(BuddyLib.Buddy calldata base, bool GPD, bool recessiveBonus) external pure returns (uint256); function calcApop(uint256 totalProduced) external view returns (uint256); function replicatePreview( int8[6] calldata dominantLock, int8[24] calldata recessiveSwap, uint256 grossGPD ) external view returns (uint256); function repBuddy( BuddyLib.Buddy calldata base, int8[6] calldata dominantLock, int8[24] calldata recessiveSwap ) external returns (uint256); function simpleReplicatePreview(uint256 grossGPD) external view returns (uint256); function simpleRepBuddy(BuddyLib.Buddy calldata base) external returns (uint256); function calcReps(uint8 gen) external returns (uint8); function calcPeg() external view returns (uint256); function getRandom() external; function getBurnPercent() external view returns (uint256); function getStartingGoo() external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title ERC721 token receiver interface * @dev Interface for any contract that wants to support safeTransfers * from ERC721 asset contracts. */ interface IERC721Receiver { /** * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom} * by `operator` from `from`, this function is called. * * It must return its Solidity selector to confirm the token transfer. * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted. * * The selector can be obtained in Solidity with `IERC721.onERC721Received.selector`. */ function onERC721Received( address operator, address from, uint256 tokenId, bytes calldata data ) external returns (bytes4); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC721.sol"; import "./IERC721Receiver.sol"; import "./extensions/IERC721Metadata.sol"; import "../../utils/Address.sol"; import "../../utils/Context.sol"; import "../../utils/Strings.sol"; import "../../utils/introspection/ERC165.sol"; /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata extension, but not including the Enumerable extension, which is available separately as * {ERC721Enumerable}. */ contract ERC721 is Context, ERC165, IERC721, IERC721Metadata { using Address for address; using Strings for uint256; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) private _owners; // Mapping owner address to token count mapping(address => uint256) private _balances; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; /** * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection. */ constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) { return interfaceId == type(IERC721).interfaceId || interfaceId == type(IERC721Metadata).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "ERC721: balance query for the zero address"); return _balances[owner]; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { address owner = _owners[tokenId]; require(owner != address(0), "ERC721: owner query for nonexistent token"); return owner; } /** * @dev See {IERC721Metadata-name}. */ function name() public view virtual override returns (string memory) { return _name; } /** * @dev See {IERC721Metadata-symbol}. */ function symbol() public view virtual override returns (string memory) { return _symbol; } /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token"); string memory baseURI = _baseURI(); return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : ""; } /** * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each * token will be the concatenation of the `baseURI` and the `tokenId`. Empty * by default, can be overriden in child contracts. */ function _baseURI() internal view virtual returns (string memory) { return ""; } /** * @dev See {IERC721-approve}. */ function approve(address to, uint256 tokenId) public virtual override { address owner = ERC721.ownerOf(tokenId); require(to != owner, "ERC721: approval to current owner"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "ERC721: approve caller is not owner nor approved for all" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "ERC721: approved query for nonexistent token"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "ERC721: approve to caller"); _operatorApprovals[_msgSender()][operator] = approved; emit ApprovalForAll(_msgSender(), operator, approved); } /** * @dev See {IERC721-isApprovedForAll}. */ function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) { return _operatorApprovals[owner][operator]; } /** * @dev See {IERC721-transferFrom}. */ function transferFrom( address from, address to, uint256 tokenId ) public virtual override { //solhint-disable-next-line max-line-length require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _transfer(from, to, tokenId); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId ) public virtual override { safeTransferFrom(from, to, tokenId, ""); } /** * @dev See {IERC721-safeTransferFrom}. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public virtual override { require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved"); _safeTransfer(from, to, tokenId, _data); } /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * `_data` is additional data, it has no specified format and it is sent in call to `to`. * * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g. * implement alternative mechanisms to perform token transfer, such as signature-based. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeTransfer( address from, address to, uint256 tokenId, bytes memory _data ) internal virtual { _transfer(from, to, tokenId); require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer"); } /** * @dev Returns whether `tokenId` exists. * * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}. * * Tokens start existing when they are minted (`_mint`), * and stop existing when they are burned (`_burn`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return _owners[tokenId] != address(0); } /** * @dev Returns whether `spender` is allowed to manage `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) { require(_exists(tokenId), "ERC721: operator query for nonexistent token"); address owner = ERC721.ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `tokenId` and transfers it to `to`. * * Requirements: * * - `tokenId` must not exist. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 tokenId) internal virtual { _safeMint(to, tokenId, ""); } /** * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is * forwarded in {IERC721Receiver-onERC721Received} to contract recipients. */ function _safeMint( address to, uint256 tokenId, bytes memory _data ) internal virtual { _mint(to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer" ); } /** * @dev Mints `tokenId` and transfers it to `to`. * * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible * * Requirements: * * - `tokenId` must not exist. * - `to` cannot be the zero address. * * Emits a {Transfer} event. */ function _mint(address to, uint256 tokenId) internal virtual { require(to != address(0), "ERC721: mint to the zero address"); require(!_exists(tokenId), "ERC721: token already minted"); _beforeTokenTransfer(address(0), to, tokenId); _balances[to] += 1; _owners[tokenId] = to; emit Transfer(address(0), to, tokenId); } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual { address owner = ERC721.ownerOf(tokenId); _beforeTokenTransfer(owner, address(0), tokenId); // Clear approvals _approve(address(0), tokenId); _balances[owner] -= 1; delete _owners[tokenId]; emit Transfer(owner, address(0), tokenId); } /** * @dev Transfers `tokenId` from `from` to `to`. * As opposed to {transferFrom}, this imposes no restrictions on msg.sender. * * Requirements: * * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * * Emits a {Transfer} event. */ function _transfer( address from, address to, uint256 tokenId ) internal virtual { require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); require(to != address(0), "ERC721: transfer to the zero address"); _beforeTokenTransfer(from, to, tokenId); // Clear approvals from the previous owner _approve(address(0), tokenId); _balances[from] -= 1; _balances[to] += 1; _owners[tokenId] = to; emit Transfer(from, to, tokenId); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(ERC721.ownerOf(tokenId), to, tokenId); } /** * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address. * The call is not executed if the target address is not a contract. * * @param from address representing the previous owner of the given token ID * @param to target address that will receive the tokens * @param tokenId uint256 ID of the token to be transferred * @param _data bytes optional data to send along with the call * @return bool whether the call correctly returned the expected magic value */ function _checkOnERC721Received( address from, address to, uint256 tokenId, bytes memory _data ) private returns (bool) { if (to.isContract()) { try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) { return retval == IERC721Receiver.onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert("ERC721: transfer to non ERC721Receiver implementer"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` and `to` are never both zero. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../ERC721.sol"; import "./IERC721Enumerable.sol"; /** * @dev This implements an optional extension of {ERC721} defined in the EIP that adds * enumerability of all the token ids in the contract as well as all token ids owned by each * account. */ abstract contract ERC721Enumerable is ERC721, IERC721Enumerable { // Mapping from owner to list of owned token IDs mapping(address => mapping(uint256 => uint256)) private _ownedTokens; // Mapping from token ID to index of the owner tokens list mapping(uint256 => uint256) private _ownedTokensIndex; // Array with all token ids, used for enumeration uint256[] private _allTokens; // Mapping from token id to position in the allTokens array mapping(uint256 => uint256) private _allTokensIndex; /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) { return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) { require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds"); return _ownedTokens[owner][index]; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _allTokens.length; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds"); return _allTokens[index]; } /** * @dev Hook that is called before any token transfer. This includes minting * and burning. * * Calling conditions: * * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be * transferred to `to`. * - When `from` is zero, `tokenId` will be minted for `to`. * - When `to` is zero, ``from``'s `tokenId` will be burned. * - `from` cannot be the zero address. * - `to` cannot be the zero address. * * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks]. */ function _beforeTokenTransfer( address from, address to, uint256 tokenId ) internal virtual override { super._beforeTokenTransfer(from, to, tokenId); if (from == address(0)) { _addTokenToAllTokensEnumeration(tokenId); } else if (from != to) { _removeTokenFromOwnerEnumeration(from, tokenId); } if (to == address(0)) { _removeTokenFromAllTokensEnumeration(tokenId); } else if (to != from) { _addTokenToOwnerEnumeration(to, tokenId); } } /** * @dev Private function to add a token to this extension's ownership-tracking data structures. * @param to address representing the new owner of the given token ID * @param tokenId uint256 ID of the token to be added to the tokens list of the given address */ function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private { uint256 length = ERC721.balanceOf(to); _ownedTokens[to][length] = tokenId; _ownedTokensIndex[tokenId] = length; } /** * @dev Private function to add a token to this extension's token tracking data structures. * @param tokenId uint256 ID of the token to be added to the tokens list */ function _addTokenToAllTokensEnumeration(uint256 tokenId) private { _allTokensIndex[tokenId] = _allTokens.length; _allTokens.push(tokenId); } /** * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for * gas optimizations e.g. when performing a transfer operation (avoiding double writes). * This has O(1) time complexity, but alters the order of the _ownedTokens array. * @param from address representing the previous owner of the given token ID * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address */ function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private { // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = ERC721.balanceOf(from) - 1; uint256 tokenIndex = _ownedTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary if (tokenIndex != lastTokenIndex) { uint256 lastTokenId = _ownedTokens[from][lastTokenIndex]; _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index } // This also deletes the contents at the last position of the array delete _ownedTokensIndex[tokenId]; delete _ownedTokens[from][lastTokenIndex]; } /** * @dev Private function to remove a token from this extension's token tracking data structures. * This has O(1) time complexity, but alters the order of the _allTokens array. * @param tokenId uint256 ID of the token to be removed from the tokens list */ function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private { // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and // then delete the last slot (swap and pop). uint256 lastTokenIndex = _allTokens.length - 1; uint256 tokenIndex = _allTokensIndex[tokenId]; // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding // an 'if' statement (like in _removeTokenFromOwnerEnumeration) uint256 lastTokenId = _allTokens[lastTokenIndex]; _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index // This also deletes the contents at the last position of the array delete _allTokensIndex[tokenId]; _allTokens.pop(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../ERC721.sol"; /** * @dev ERC721 token with storage based token URI management. */ abstract contract ERC721URIStorage is ERC721 { using Strings for uint256; // Optional mapping for token URIs mapping(uint256 => string) private _tokenURIs; /** * @dev See {IERC721Metadata-tokenURI}. */ function tokenURI(uint256 tokenId) public view virtual override returns (string memory) { require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token"); string memory _tokenURI = _tokenURIs[tokenId]; string memory base = _baseURI(); // If there is no base URI, return the token URI. if (bytes(base).length == 0) { return _tokenURI; } // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked). if (bytes(_tokenURI).length > 0) { return string(abi.encodePacked(base, _tokenURI)); } return super.tokenURI(tokenId); } /** * @dev Sets `_tokenURI` as the tokenURI of `tokenId`. * * Requirements: * * - `tokenId` must exist. */ function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual { require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token"); _tokenURIs[tokenId] = _tokenURI; } /** * @dev Destroys `tokenId`. * The approval is cleared when the token is burned. * * Requirements: * * - `tokenId` must exist. * * Emits a {Transfer} event. */ function _burn(uint256 tokenId) internal virtual override { super._burn(tokenId); if (bytes(_tokenURIs[tokenId]).length != 0) { delete _tokenURIs[tokenId]; } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which allows children to implement an emergency stop * mechanism that can be triggered by an authorized account. * * This module is used through inheritance. It will make available the * modifiers `whenNotPaused` and `whenPaused`, which can be applied to * the functions of your contract. Note that they will not be pausable by * simply including this module, only once the modifiers are put in place. */ abstract contract Pausable is Context { /** * @dev Emitted when the pause is triggered by `account`. */ event Paused(address account); /** * @dev Emitted when the pause is lifted by `account`. */ event Unpaused(address account); bool private _paused; /** * @dev Initializes the contract in unpaused state. */ constructor() { _paused = false; } /** * @dev Returns true if the contract is paused, and false otherwise. */ function paused() public view virtual returns (bool) { return _paused; } /** * @dev Modifier to make a function callable only when the contract is not paused. * * Requirements: * * - The contract must not be paused. */ modifier whenNotPaused() { require(!paused(), "Pausable: paused"); _; } /** * @dev Modifier to make a function callable only when the contract is paused. * * Requirements: * * - The contract must be paused. */ modifier whenPaused() { require(paused(), "Pausable: not paused"); _; } /** * @dev Triggers stopped state. * * Requirements: * * - The contract must not be paused. */ function _pause() internal virtual whenNotPaused { _paused = true; emit Paused(_msgSender()); } /** * @dev Returns to normal state. * * Requirements: * * - The contract must be paused. */ function _unpause() internal virtual whenPaused { _paused = false; emit Unpaused(_msgSender()); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../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. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _setOwner(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _setOwner(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _setOwner(newOwner); } function _setOwner(address newOwner) private { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @title Counters * @author Matt Condon (@shrugs) * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number * of elements in a mapping, issuing ERC721 ids, or counting request ids. * * Include with `using Counters for Counters.Counter;` */ library Counters { struct Counter { // This variable should never be directly accessed by users of the library: interactions must be restricted to // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add // this feature: see https://github.com/ethereum/solidity/issues/4637 uint256 _value; // default: 0 } function current(Counter storage counter) internal view returns (uint256) { return counter._value; } function increment(Counter storage counter) internal { unchecked { counter._value += 1; } } function decrement(Counter storage counter) internal { uint256 value = counter._value; require(value > 0, "Counter: decrement overflow"); unchecked { counter._value = value - 1; } } function reset(Counter storage counter) internal { counter._value = 0; } }
// SPDX-License-Identifier: MIT pragma solidity 0.8.9; import "../libraries/BuddyLib.sol"; interface IMutations { function getMutation( uint8 species, uint8 trait, uint8 r1, uint8 r2, uint8 r3, uint8 r4, uint8 traitType ) external view returns (uint8); function getRarity(uint8 species, uint256 index) external view returns (uint256); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../../utils/introspection/IERC165.sol"; /** * @dev Required interface of an ERC721 compliant contract. */ interface IERC721 is IERC165 { /** * @dev Emitted when `tokenId` token is transferred from `from` to `to`. */ event Transfer(address indexed from, address indexed to, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token. */ event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId); /** * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets. */ event ApprovalForAll(address indexed owner, address indexed operator, bool approved); /** * @dev Returns the number of tokens in ``owner``'s account. */ function balanceOf(address owner) external view returns (uint256 balance); /** * @dev Returns the owner of the `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function ownerOf(uint256 tokenId) external view returns (address owner); /** * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional metadata extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Metadata is IERC721 { /** * @dev Returns the token collection name. */ function name() external view returns (string memory); /** * @dev Returns the token collection symbol. */ function symbol() external view returns (string memory); /** * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token. */ function tokenURI(uint256 tokenId) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Provides information about the current execution context, including the * sender of the transaction and its data. While these are generally available * via msg.sender and msg.data, they should not be accessed in such a direct * manner, since when dealing with meta-transactions the account sending and * paying for execution may not be the actual sender (as far as an application * is concerned). * * This contract is only required for intermediate, library-like contracts. */ abstract contract Context { function _msgSender() internal view virtual returns (address) { return msg.sender; } function _msgData() internal view virtual returns (bytes calldata) { return msg.data; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; /** * @dev Converts a `uint256` to its ASCII `string` decimal representation. */ function toString(uint256 value) internal pure returns (string memory) { // Inspired by OraclizeAPI's implementation - MIT licence // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol if (value == 0) { return "0"; } uint256 temp = value; uint256 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); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation. */ function toHexString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0x00"; } uint256 temp = value; uint256 length = 0; while (temp != 0) { length++; temp >>= 8; } return toHexString(value, length); } /** * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length. */ function toHexString(uint256 value, uint256 length) internal pure returns (string memory) { bytes memory buffer = new bytes(2 * length + 2); buffer[0] = "0"; buffer[1] = "x"; for (uint256 i = 2 * length + 1; i > 1; --i) { buffer[i] = _HEX_SYMBOLS[value & 0xf]; value >>= 4; } require(value == 0, "Strings: hex length insufficient"); return string(buffer); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./IERC165.sol"; /** * @dev Implementation of the {IERC165} interface. * * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check * for the additional interface id that will be supported. For example: * * ```solidity * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { * return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId); * } * ``` * * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation. */ abstract contract ERC165 is IERC165 { /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IERC165).interfaceId; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "../IERC721.sol"; /** * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension * @dev See https://eips.ethereum.org/EIPS/eip-721 */ interface IERC721Enumerable is IERC721 { /** * @dev Returns the total amount of tokens stored by the contract. */ function totalSupply() external view returns (uint256); /** * @dev Returns a token ID owned by `owner` at a given `index` of its token list. * Use along with {balanceOf} to enumerate all of ``owner``'s tokens. */ function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256 tokenId); /** * @dev Returns a token ID at a given `index` of all the tokens stored by the contract. * Use along with {totalSupply} to enumerate all tokens. */ function tokenByIndex(uint256 index) external view returns (uint256); }
{ "optimizer": { "enabled": true, "runs": 800 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": { "contracts/libraries/BuddyLib.sol": { "BuddyLib": "0xc0770e1978916ed43bf762ac00b0e1341ad30c78" } } }
[{"inputs":[{"internalType":"address","name":"_gooAddr","type":"address"},{"internalType":"address","name":"_nanoFactoryAddr","type":"address"},{"internalType":"address","name":"_buddyLogicAddr","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"uint256","name":"dna","type":"uint256"}],"name":"Birth","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"_buddyLogic","outputs":[{"internalType":"contract IBuddyLogic","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_goo","outputs":[{"internalType":"contract IGoo","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_nanoFactoryToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256[]","name":"receivers","type":"uint256[]"}],"name":"apoptosis","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blackHole","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyGen0","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"calcApop","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"calcClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"calcFounderClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"fertility","type":"bool"},{"internalType":"bool","name":"recessiveBonus","type":"bool"}],"name":"calcGGPD","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"calcPeg","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"claim","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"}],"name":"claimAll","outputs":[{"internalType":"uint256","name":"total","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"founderClaim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"generateBlackHole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproval","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBalanceByOwner","outputs":[{"internalType":"uint256","name":"balance","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBlackHole","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getBuddy","outputs":[{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint8","name":"","type":"uint8"},{"internalType":"uint24","name":"","type":"uint24"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"getMaxBalance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOwnerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getTokensByOwner","outputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"},{"internalType":"address","name":"_operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"isOperator","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastFounderClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lastFounderClaimTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"int8[6]","name":"dominantLock","type":"int8[6]"},{"internalType":"int8[24]","name":"recessiveSwap","type":"int8[24]"},{"internalType":"bool","name":"useAllBuddies","type":"bool"}],"name":"replicate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"int8[6]","name":"dominantLock","type":"int8[6]"},{"internalType":"int8[24]","name":"recessiveSwap","type":"int8[24]"}],"name":"replicatePreview","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_gooContractAddr","type":"address"}],"name":"setGooContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_logicContractAddr","type":"address"}],"name":"setLogicContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_nanoContractAddr","type":"address"}],"name":"setNanoContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"simpleReplicate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"simpleReplicatePreview","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","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":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60806040523480156200001157600080fd5b50604051620061a2380380620061a2833981016040819052620000349162000216565b604080518082018252600c81526b4d6963726f4275646469657360a01b6020808301918252835180850190945260048452634d42445960e01b908401528151919291620000849160009162000153565b5080516200009a90600190602084019062000153565b5050600b805460ff1916905550620000b233620000f9565b601080546001600160a01b039485166001600160a01b031991821617909155600f80549385169382169390931790925560118054919093169116179055426013556200029d565b600b80546001600160a01b03838116610100818102610100600160a81b031985161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b828054620001619062000260565b90600052602060002090601f016020900481019282620001855760008555620001d0565b82601f10620001a057805160ff1916838001178555620001d0565b82800160010185558215620001d0579182015b82811115620001d0578251825591602001919060010190620001b3565b50620001de929150620001e2565b5090565b5b80821115620001de5760008155600101620001e3565b80516001600160a01b03811681146200021157600080fd5b919050565b6000806000606084860312156200022c57600080fd5b6200023784620001f9565b92506200024760208501620001f9565b91506200025760408501620001f9565b90509250925092565b600181811c908216806200027557607f821691505b602082108114156200029757634e487b7160e01b600052602260045260246000fd5b50919050565b615ef580620002ad6000396000f3fe608060405234801561001057600080fd5b50600436106103625760003560e01c806370a08231116101c85780639f6c2a8d11610104578063e949a9c0116100a2578063f2fde38b1161007c578063f2fde38b1461079b578063f658518a146107ae578063fe1b70c2146107c1578063fe829e87146107d457600080fd5b8063e949a9c01461076c578063e985e9c514610775578063ec9c4a431461078857600080fd5b8063c0011eec116100de578063c0011eec14610736578063c84c180b1461073e578063c87b56dd14610751578063cdb5415d1461076457600080fd5b80639f6c2a8d146106fd578063a22cb46514610710578063b88d4fde1461072357600080fd5b80638456cb59116101715780638da5cb5b1161014b5780638da5cb5b146106c457806395d89b41146106da5780639d13ac13146106e25780639e90f9aa146106f557600080fd5b80638456cb59146106a257806387e1aede146106aa5780638ad6dfdf146106bd57600080fd5b80638117b67a116101a25780638117b67a14610669578063836387101461067c578063844cb9f01461068f57600080fd5b806370a082311461063b578063715018a61461064e578063776e8eee1461065657600080fd5b8063379607f5116102a25780635aa4470f11610240578063616306ee1161021a578063616306ee146105495780636352211e1461055c578063640f845d1461056f5780636bf696991461057857600080fd5b80635aa4470f146105185780635c975abb1461052b5780635ec434981461053657600080fd5b80634610a32a1161027c5780634610a32a146104ca5780634d90769b146104df5780634f6ccce7146104f257806355de33431461050557600080fd5b8063379607f51461049c5780633f4ba83a146104af57806342842e0e146104b757600080fd5b8063176ce0f51161030f57806323b872dd116102e957806323b872dd146104505780632738e8061461046357806328c77820146104765780632f745c591461048957600080fd5b8063176ce0f51461042357806318160ddd1461043657806318b8cb991461044857600080fd5b8063081812fc11610340578063081812fc146103b9578063095ea7b3146103e4578063150b7a02146103f757600080fd5b806301ffc9a71461036757806306fdde031461038f57806307c20c8f146103a4575b600080fd5b61037a61037536600461512f565b6107e7565b60405190151581526020015b60405180910390f35b6103976107f8565b60405161038691906151a4565b6103b76103b23660046151c5565b61088a565b005b6103cc6103c7366004615221565b61141c565b6040516001600160a01b039091168152602001610386565b6103b76103f2366004615256565b6114b1565b61040a6104053660046152f1565b6115c7565b6040516001600160e01b03199091168152602001610386565b6103b76104313660046153b1565b6115d8565b6008545b604051908152602001610386565b61043a61165a565b6103b761045e3660046153cc565b611735565b61043a610471366004615408565b6117bc565b61043a6104843660046154ca565b611857565b61043a610497366004615256565b6118f7565b61043a6104aa366004615221565b61199f565b6103b7611ba3565b6103b76104c53660046153cc565b611c0d565b6104d2611c28565b60405161038691906154ff565b6103b76104ed3660046153b1565b611cec565b61043a610500366004615221565b611d6e565b6103b7610513366004615221565b611e12565b6103b76105263660046153b1565b611f97565b600b5460ff1661037a565b61043a610544366004615221565b612019565b600f546103cc906001600160a01b031681565b6103cc61056a366004615221565b6120ae565b61043a60135481565b6105df610586366004615221565b6000908152600e6020526040902080546002820154600383015460048401546005850154600686015460079096015460ff9586169761010086048716976201000087048816976301000000880481169716959493929091565b6040805160ff9b8c168152998b1660208b0152978a169789019790975297909416606087015262ffffff909216608086015260a085015260c084015260e083015261010082019290925261012081019190915261014001610386565b61043a6106493660046153b1565b612139565b6103b76121d3565b6011546103cc906001600160a01b031681565b6103b76106773660046153b1565b61223d565b6103cc61068a366004615221565b612448565b61043a61069d366004615221565b612453565b6103b7612508565b6103b76106b8366004615543565b612570565b600161043a565b600b5461010090046001600160a01b03166103cc565b610397612859565b61043a6106f0366004615604565b612868565b61043a600181565b6103b761070b366004615221565b612a95565b6103b761071e3660046156b3565b6131e6565b6103b76107313660046152f1565b6132ab565b6103b7613339565b61043a61074c366004615221565b61396c565b61039761075f366004615221565b613b86565b61043a613b91565b61043a60125481565b61037a6107833660046156ea565b613c13565b6010546103cc906001600160a01b031681565b6103b76107a93660046153b1565b613c70565b6103cc6107bc366004615221565b613d58565b61043a6107cf366004615221565b613d63565b61043a6107e2366004615221565b613daa565b60006107f282613fc8565b92915050565b6060600080546108079061571d565b80601f01602080910402602001604051908101604052809291908181526020018280546108339061571d565b80156108805780601f1061085557610100808354040283529160200191610880565b820191906000526020600020905b81548152906001019060200180831161086357829003601f168201915b5050505050905090565b83610894816120ae565b6001600160a01b0316336001600160a01b0316146108e85760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064015b60405180910390fd5b600b5460ff161561092e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000610989868660068060200260405190810160405280929190826006602002808284376000920191909152505060408051610300818101909252915088906018908390839080828437600092019190915250612868915050565b601054604051631398fee160e31b8152600481018990529192506060916000916001600160a01b031690639cc7f7089060240160206040518083038186803b1580156109d457600080fd5b505afa1580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c9190615752565b90508415610b1057610a1c611c28565b915060005b8251811015610b0e5788838281518110610a3d57610a3d61576b565b60200260200101511415610a5057610afc565b60105483516001600160a01b0390911690639cc7f70890859084908110610a7957610a7961576b565b60200260200101516040518263ffffffff1660e01b8152600401610a9f91815260200190565b60206040518083038186803b158015610ab757600080fd5b505afa158015610acb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aef9190615752565b610af99083615797565b91505b80610b06816157af565b915050610a21565b505b82811015610b605760405162461bcd60e51b815260206004820152601a60248201527f596f7520646f206e6f74206861766520656e6f75676820474f4f00000000000060448201526064016108df565b6010546040516319942df560e31b8152600481018a9052600160248201526000916001600160a01b03169063cca16fa89060440160206040518083038186803b158015610bac57600080fd5b505afa158015610bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be49190615752565b905083811015610c365760405162461bcd60e51b815260206004820152601660248201527f796f75206e65656420676f6f20616c6c6f77616e63650000000000000000000060448201526064016108df565b838615610f1657601054604051631398fee160e31b8152600481018c90526000916001600160a01b031690639cc7f7089060240160206040518083038186803b158015610c8257600080fd5b505afa158015610c96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cba9190615752565b905081811015610f1457610cce81836157ca565b915060005b8551811015610f06578b868281518110610cef57610cef61576b565b60200260200101511415610d0257610ef4565b6000868281518110610d1657610d1661576b565b6020908102919091010151601054604051631398fee160e31b8152600481018390529192506000916001600160a01b0390911690639cc7f7089060240160206040518083038186803b158015610d6b57600080fd5b505afa158015610d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da39190615752565b905084811015610e5257601054604051638856f77960e01b8152600160048201819052602482018590526044820152606481018390526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015610e0857600080fd5b505af1158015610e1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4091906157e1565b50610e4b81866157ca565b9450610ef1565b601054604051638856f77960e01b8152600160048201819052602482018590526044820152606481018790526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015610ead57600080fd5b505af1158015610ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee591906157e1565b50600094505050610f06565b50505b80610efe816157af565b915050610cd3565b50610f118183615797565b91505b505b601054604051638856f77960e01b8152600160048201819052602482018d90526044820152606481018390526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015610f7157600080fd5b505af1158015610f85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa991906157e1565b506010546011546040805163096cf85d60e01b815290516001600160a01b039384169363b390c0ab93600193606493919092169163096cf85d916004808301926020929190829003018186803b15801561100257600080fd5b505afa158015611016573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103a9190615752565b611044908a6157fe565b61104e9190615833565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b50505060008b8152600e60205260409020600280820180549293506001929091906110d590849062010000900460ff16615847565b825460ff9182166101009390930a92830291909202199091161790555060115460405163420bfa6160e11b81526000916001600160a01b031690638417f4c2906111279085908f908f90600401615b50565b602060405180830381600087803b15801561114157600080fd5b505af1158015611155573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111799190615752565b604051634a7dd52360e01b81526004810182905290915060009073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b1580156111cb57600080fd5b505af41580156111df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112039190615c59565b61014081018e90526011546040808301519051632942467960e11b815260ff90911660048201529192506001600160a01b0316906352848cf290602401602060405180830381600087803b15801561125a57600080fd5b505af115801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112929190615d1a565b60ff1660608201526011546040805163aacc5a1760e01b815290516001600160a01b039092169163aacc5a179160048082019260009290919082900301818387803b1580156112e057600080fd5b505af11580156112f4573d6000803e3d6000fd5b5050505060c08101829052600061130a33613fed565b6000818152600e602090815260409091208451815460ff191660ff909116178155908401519192508391611344906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c080850151600385015560e08501516004850155908401516005840155610120840151600684015561014090930151600790920191909155908301519051339083907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a45050505050505050505050505050565b6000818152600260205260408120546001600160a01b03166114955760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108df565b506000908152600460205260409020546001600160a01b031690565b60006114bc826120ae565b9050806001600160a01b0316836001600160a01b0316141561152a5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016108df565b336001600160a01b038216148061154657506115468133613c13565b6115b85760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016108df565b6115c28383614043565b505050565b630a85bd0160e11b5b949350505050565b600b546001600160a01b036101009091041633146116385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600080611665611c28565b905060005b81518110156117305760105482516001600160a01b0390911690639cc7f7089084908490811061169c5761169c61576b565b60200260200101516040518263ffffffff1660e01b81526004016116c291815260200190565b60206040518083038186803b1580156116da57600080fd5b505afa1580156116ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117129190615752565b61171c9084615797565b925080611728816157af565b91505061166a565b505090565b61173f33826140b1565b6117b15760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016108df565b6115c2838383614180565b6000838152600e60205260408082206011549151630aac6d3b60e31b815290916001600160a01b03169063556369d8906117fe90849088908890600401615d35565b60206040518083038186803b15801561181657600080fd5b505afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190615752565b95945050505050565b6000611865600b5460ff1690565b156118a55760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b60005b82518110156118f1576118d38382815181106118c6576118c661576b565b602002602001015161199f565b6118dd9083615797565b9150806118e9816157af565b9150506118a8565b50919050565b600061190283612139565b82106119765760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016108df565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6000816119ab816120ae565b6001600160a01b0316336001600160a01b0316146119fa5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff1615611a405760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000838152600e6020526040902060028101546301000000900460ff1615611aaa5760405162461bcd60e51b815260206004820152601960248201527f5370656369616c7320646f206e6f74206d616b6520474f4f210000000000000060448201526064016108df565b61012c816006015442611abd91906157ca565b11611b0a5760405162461bcd60e51b815260206004820152601160248201527f436c61696d206f6e20636f6f6c646f776e00000000000000000000000000000060448201526064016108df565b611b1384612019565b925042816006018190555082816005016000828254611b329190615797565b9091555050601054604051630d9778e560e11b815260048101869052602481018590526001600160a01b0390911690631b2ef1ca90604401600060405180830381600087803b158015611b8457600080fd5b505af1158015611b98573d6000803e3d6000fd5b505050505050919050565b600b546001600160a01b03610100909104163314611c035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b611c0b61433f565b565b6115c2838383604051806020016040528060008152506132ab565b60606000611c3533612139565b905080611c5057505060408051600081526020810190915290565b60008167ffffffffffffffff811115611c6b57611c6b615280565b604051908082528060200260200182016040528015611c94578160200160208202803683370190505b50905060005b82811015611ce1576000611cae33836118f7565b905080838381518110611cc357611cc361576b565b60209081029190910101525080611cd9816157af565b915050611c9a565b5092915050565b5090565b600b546001600160a01b03610100909104163314611d4c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6000611d7960085490565b8210611ded5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016108df565b60088281548110611e0057611e0061576b565b90600052602060002001549050919050565b80611e1c816120ae565b6001600160a01b0316336001600160a01b031614611e6b5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff1615611eb15760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000828152600e6020526040812090611ec984613daa565b6013549091504290611ede9062093a80615797565b8110611eea5760006012555b60068301819055601254611f0357601282905560138190555b6010546040516390dd262760e01b81526001600482015260248101879052604481018490526001600160a01b03909116906390dd262790606401602060405180830381600087803b158015611f5757600080fd5b505af1158015611f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8f91906157e1565b505050505050565b600b546001600160a01b03610100909104163314611ff75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600e6020526040808220601154915163c93d78ef60e01b815290916001600160a01b03169063c93d78ef90612057908490600401615d5c565b60206040518083038186803b15801561206f57600080fd5b505afa158015612083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a79190615752565b9392505050565b6000818152600260205260408120546001600160a01b0316806107f25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016108df565b60006001600160a01b0382166121b75760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016108df565b506001600160a01b031660009081526003602052604090205490565b600b546001600160a01b036101009091041633146122335760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b611c0b60006143db565b600b546001600160a01b0361010090910416331461229d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b604051634a7dd52360e01b81526000600482018190529073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b1580156122ec57600080fd5b505af4158015612300573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123249190615c59565b600160a08201529050600061233883613fed565b6000818152600e602090815260409091208451815460ff191660ff909116178155908401519192508391612372906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c080850151600385015560e085015160048501559084015160058401556101208401516006840155610140909301516007909201919091559083015190516001600160a01b0385169083907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a4505050565b60006107f2826120ae565b6000818152600e60205260408082206011549151630aac6d3b60e31b8152909183916001600160a01b039091169063556369d89061249990859085908190600401615d35565b60206040518083038186803b1580156124b157600080fd5b505afa1580156124c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e99190615752565b6124f490605a6157fe565b90506115d081670de0b6b3a76400006157fe565b600b546001600160a01b036101009091041633146125685760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b611c0b61444c565b8161257a816120ae565b6001600160a01b0316336001600160a01b0316146125c95760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff161561260f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000838152600e6020526040902060028101546301000000900460ff16156126795760405162461bcd60e51b815260206004820152601460248201527f5370656369616c732063616e6e6f742041706f7000000000000000000000000060448201526064016108df565b60648160050154116126d95760405162461bcd60e51b815260206004820152602360248201527f4275646479206d7573742070726f64756365206174206c656173742031303020604482015262474f4f60e81b60648201526084016108df565b60006126e485613d63565b905060005b845181101561284457858582815181106127055761270561576b565b6020026020010151141561271857612832565b600085828151811061272c5761272c61576b565b60200260200101519050600061274182612453565b9050808411156127c357601054604051630d9778e560e11b815260048101839052602481018490526001600160a01b0390911690631b2ef1ca90604401600060405180830381600087803b15801561279857600080fd5b505af11580156127ac573d6000803e3d6000fd5b5050505080846127bc91906157ca565b935061282f565b601054604051630d9778e560e11b815260048101869052602481018490526001600160a01b0390911690631b2ef1ca90604401600060405180830381600087803b15801561281057600080fd5b505af1158015612824573d6000803e3d6000fd5b505050505050612844565b50505b8061283c816157af565b9150506126e9565b506128523361dead87611735565b5050505050565b6060600180546108079061571d565b6000838152600e6020526040812060028101546301000000900460ff16156128d25760405162461bcd60e51b815260206004820152601960248201527f5370656369616c732063616e6e6f74205265706c69636174650000000000000060448201526064016108df565b600281015460ff610100820481166201000090920416106129275760405162461bcd60e51b815260206004820152600f60248201526e213ab2323c9034b9903130b93932b760891b60448201526064016108df565b601160009054906101000a90046001600160a01b03166001600160a01b031663dcaf4fe36040518163ffffffff1660e01b815260040160206040518083038186803b15801561297557600080fd5b505afa158015612989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ad9190615d1a565b600282015460ff9182169116106129f75760405162461bcd60e51b815260206004820152600e60248201526d26a0ac1023a2a722a920aa24a7a760911b60448201526064016108df565b6000612a0686600060016117bc565b60115460405163bb1dd8fd60e01b81529192506001600160a01b03169063bb1dd8fd90612a3b90889088908690600401615d6b565b60206040518083038186803b158015612a5357600080fd5b505afa158015612a67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8b9190615752565b9695505050505050565b80612a9f816120ae565b6001600160a01b0316336001600160a01b031614612aee5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff1615612b345760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000612b3f8361396c565b601054604051631398fee160e31b8152600481018690529192506000916001600160a01b0390911690639cc7f7089060240160206040518083038186803b158015612b8957600080fd5b505afa158015612b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc19190615752565b905081811015612c135760405162461bcd60e51b815260206004820152601960248201527f796f75206e65656420676f6f20746f207265706c69636174650000000000000060448201526064016108df565b6010546040516319942df560e31b815260048101869052600160248201526000916001600160a01b03169063cca16fa89060440160206040518083038186803b158015612c5f57600080fd5b505afa158015612c73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c979190615752565b905082811015612ce95760405162461bcd60e51b815260206004820152601660248201527f796f75206e65656420676f6f20616c6c6f77616e63650000000000000000000060448201526064016108df565b601054604051638856f77960e01b8152600160048201819052602482018890526044820152606481018590526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015612d4457600080fd5b505af1158015612d58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7c91906157e1565b506010546011546040805163096cf85d60e01b815290516001600160a01b039384169363b390c0ab93600193606493919092169163096cf85d916004808301926020929190829003018186803b158015612dd557600080fd5b505afa158015612de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0d9190615752565b612e1790886157fe565b612e219190615833565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b158015612e5f57600080fd5b505af1158015612e73573d6000803e3d6000fd5b5050506000868152600e6020526040902060028082018054929350600192909190612ea890849062010000900460ff16615847565b825460ff9182166101009390930a9283029190920219909116179055506011546040516308ea004360e41b81526000916001600160a01b031690638ea0043090612ef6908590600401615d5c565b602060405180830381600087803b158015612f1057600080fd5b505af1158015612f24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f489190615752565b604051634a7dd52360e01b81526004810182905290915060009073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b158015612f9a57600080fd5b505af4158015612fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd29190615c59565b61014081018990526011546040808301519051632942467960e11b815260ff90911660048201529192506001600160a01b0316906352848cf290602401602060405180830381600087803b15801561302957600080fd5b505af115801561303d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130619190615d1a565b60ff1660608201526011546040805163aacc5a1760e01b815290516001600160a01b039092169163aacc5a179160048082019260009290919082900301818387803b1580156130af57600080fd5b505af11580156130c3573d6000803e3d6000fd5b5050505060c0810182905260006130d933613fed565b6000818152600e602090815260409091208451815460ff191660ff909116178155908401519192508391613113906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c080850151600385015560e08501516004850155908401516005840155610120840151600684015561014090930151600790920191909155908301519051339083907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a4505050505050505050565b6001600160a01b03821633141561323f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016108df565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6132b533836140b1565b6133275760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016108df565b613333848484846144c7565b50505050565b600b5460ff161561337f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b600f546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156133c357600080fd5b505afa1580156133d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fb9190615752565b9050670de0b6b3a76400008110156134555760405162461bcd60e51b815260206004820152601960248201527f796f75206e656564206e616e6f20746f206275792067656e300000000000000060448201526064016108df565b600f54604051636eb1769f60e11b81523360048201523060248201526000916001600160a01b03169063dd62ed3e9060440160206040518083038186803b15801561349f57600080fd5b505afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190615752565b9050670de0b6b3a76400008110156135315760405162461bcd60e51b815260206004820152601860248201527f796f75206e656564206e616e6f20616c6c6f77616e636520000000000000000060448201526064016108df565b600b61353b614545565b11806135685750600b5461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6135b45760405162461bcd60e51b815260206004820152601a60248201527f596f75206d757374207761697420666f7220666f756e6465727300000000000060448201526064016108df565b600f546040516323b872dd60e01b815233600482015261dead6024820152670de0b6b3a764000060448201526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561360f57600080fd5b505af1158015613623573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061364791906157e1565b50600061365333613fed565b601154604051631a9caab960e01b8152600481018390529192506000916001600160a01b0390911690631a9caab990602401602060405180830381600087803b15801561369f57600080fd5b505af11580156136b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d79190615752565b604051634a7dd52360e01b81526004810182905290915060009073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b15801561372957600080fd5b505af415801561373d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137619190615c59565b9050600b831161377357600260a08201525b6000838152600e602090815260409091208251815460ff191660ff909116178155908201518291906137ab906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c0840151600384015560e0840151600480850191909155908401516005840155610120840151600684015561014090930151600790920191909155601054601154825163f13060e960e01b815292516001600160a01b0392831694631b2ef1ca9489949093169263f13060e99281830192602092829003018186803b15801561389357600080fd5b505afa1580156138a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138cb9190615752565b6138dd90670de0b6b3a76400006157fe565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561391b57600080fd5b505af115801561392f573d6000803e3d6000fd5b5050505060c0810151604051339085907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a45050505050565b6000818152600e6020526040812060028101546301000000900460ff16156139d65760405162461bcd60e51b815260206004820152601960248201527f5370656369616c732063616e6e6f74205265706c69636174650000000000000060448201526064016108df565b600281015460ff61010082048116620100009092041610613a2b5760405162461bcd60e51b815260206004820152600f60248201526e213ab2323c9034b9903130b93932b760891b60448201526064016108df565b601160009054906101000a90046001600160a01b03166001600160a01b031663dcaf4fe36040518163ffffffff1660e01b815260040160206040518083038186803b158015613a7957600080fd5b505afa158015613a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab19190615d1a565b600282015460ff918216911610613afb5760405162461bcd60e51b815260206004820152600e60248201526d26a0ac1023a2a722a920aa24a7a760911b60448201526064016108df565b6000613b09846000806117bc565b60115460405163c84c180b60e01b8152600481018390529192506001600160a01b03169063c84c180b9060240160206040518083038186803b158015613b4e57600080fd5b505afa158015613b62573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d09190615752565b60606107f282614550565b6011546040805163cdb5415d60e01b815290516000926001600160a01b03169163cdb5415d916004808301926020929190829003018186803b158015613bd657600080fd5b505afa158015613bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c0e9190615752565b905090565b60006001600160a01b0382167358807bad0b376efc12f5ad86aac70e78ed67deae1415613c42575060016107f2565b6001600160a01b0380841660009081526005602090815260408083209386168352929052205460ff166120a7565b600b546001600160a01b03610100909104163314613cd05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b6001600160a01b038116613d4c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016108df565b613d55816143db565b50565b60006107f28261141c565b6000818152600e602052604080822060115460058201549251637f0db86160e11b815291926001600160a01b039091169163fe1b70c2916120579160040190815260200190565b6000818152600e602052604081206002808201546301000000900460ff1614613e155760405162461bcd60e51b815260206004820152600d60248201527f4e6f74206120466f756e6465720000000000000000000000000000000000000060448201526064016108df565b6006810154613e279062093a80615797565b421015613e765760405162461bcd60e51b815260206004820152601d60248201527f796f75206d7573742077616974206174206c656173742031207765656b00000060448201526064016108df565b6012541580613e945750601354613e909062093a80615797565b4210155b15613fbe5760006064601160009054906101000a90046001600160a01b03166001600160a01b031663096cf85d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613eeb57600080fd5b505afa158015613eff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f239190615752565b613f2e9060646157ca565b601054604051631398fee160e31b8152600160048201526001600160a01b0390911690639cc7f7089060240160206040518083038186803b158015613f7257600080fd5b505afa158015613f86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613faa9190615752565b613fb491906157fe565b6115d09190615833565b5050601254919050565b60006001600160e01b0319821663780e9d6360e01b14806107f257506107f282614700565b600080613ff8614545565b90506140048382614750565b614035816140118361476e565b6040516020016140219190615dd6565b604051602081830303815290604052614884565b6107f2600c80546001019055565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190614078826120ae565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b031661412a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108df565b6000614135836120ae565b9050806001600160a01b0316846001600160a01b031614806141705750836001600160a01b03166141658461141c565b6001600160a01b0316145b806115d057506115d08185613c13565b826001600160a01b0316614193826120ae565b6001600160a01b03161461420f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016108df565b6001600160a01b0382166142715760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016108df565b61427c83838361492d565b614287600082614043565b6001600160a01b03831660009081526003602052604081208054600192906142b09084906157ca565b90915550506001600160a01b03821660009081526003602052604081208054600192906142de908490615797565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b5460ff166143915760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016108df565b600b805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600b80546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff85161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600b5460ff16156144925760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b600b805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586143be3390565b6144d2848484614180565b6144de8484848461497e565b6133335760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016108df565b6000613c0e600c5490565b6000818152600260205260409020546060906001600160a01b03166145dd5760405162461bcd60e51b815260206004820152603160248201527f45524337323155524953746f726167653a2055524920717565727920666f722060448201527f6e6f6e6578697374656e7420746f6b656e00000000000000000000000000000060648201526084016108df565b6000828152600a6020526040812080546145f69061571d565b80601f01602080910402602001604051908101604052809291908181526020018280546146229061571d565b801561466f5780601f106146445761010080835404028352916020019161466f565b820191906000526020600020905b81548152906001019060200180831161465257829003601f168201915b5050505050905060006146b260408051808201909152601c81527f68747470733a2f2f6170692e6d6963726f627564646965732e696f2f00000000602082015290565b90508051600014156146c5575092915050565b8151156146f75780826040516020016146df929190615e17565b60405160208183030381529060405292505050919050565b6115d084614ad3565b60006001600160e01b031982166380ac58cd60e01b148061473157506001600160e01b03198216635b5e139f60e01b145b806107f257506301ffc9a760e01b6001600160e01b03198316146107f2565b61476a828260405180602001604052806000815250614bed565b5050565b6060816147925750506040805180820190915260018152600360fc1b602082015290565b8160005b81156147bc57806147a6816157af565b91506147b59050600a83615833565b9150614796565b60008167ffffffffffffffff8111156147d7576147d7615280565b6040519080825280601f01601f191660200182016040528015614801576020820181803683370190505b5090505b84156115d0576148166001836157ca565b9150614823600a86615e46565b61482e906030615797565b60f81b8183815181106148435761484361576b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061487d600a86615833565b9450614805565b6000828152600260205260409020546001600160a01b031661490e5760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201527f6578697374656e7420746f6b656e00000000000000000000000000000000000060648201526084016108df565b6000828152600a6020908152604090912082516115c292840190615090565b600b5460ff16156149735760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6115c2838383614c6b565b60006001600160a01b0384163b15614acb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906149c2903390899088908890600401615e5a565b602060405180830381600087803b1580156149dc57600080fd5b505af1925050508015614a0c575060408051601f3d908101601f19168201909252614a0991810190615e8c565b60015b614ab1573d808015614a3a576040519150601f19603f3d011682016040523d82523d6000602084013e614a3f565b606091505b508051614aa95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016108df565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506115d0565b5060016115d0565b6000818152600260205260409020546060906001600160a01b0316614b605760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e000000000000000000000000000000000060648201526084016108df565b6000614b9c60408051808201909152601c81527f68747470733a2f2f6170692e6d6963726f627564646965732e696f2f00000000602082015290565b90506000815111614bbc57604051806020016040528060008152506120a7565b80614bc68461476e565b604051602001614bd7929190615e17565b6040516020818303038152906040529392505050565b614bf78383614d23565b614c04600084848461497e565b6115c25760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016108df565b6001600160a01b038316614cc657614cc181600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b614ce9565b816001600160a01b0316836001600160a01b031614614ce957614ce98382614e71565b6001600160a01b038216614d00576115c281614f0e565b826001600160a01b0316826001600160a01b0316146115c2576115c28282614fbd565b6001600160a01b038216614d795760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108df565b6000818152600260205260409020546001600160a01b031615614dde5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108df565b614dea6000838361492d565b6001600160a01b0382166000908152600360205260408120805460019290614e13908490615797565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001614e7e84612139565b614e8891906157ca565b600083815260076020526040902054909150808214614edb576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090614f20906001906157ca565b60008381526009602052604081205460088054939450909284908110614f4857614f4861576b565b906000526020600020015490508060088381548110614f6957614f6961576b565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480614fa157614fa1615ea9565b6001900381819060005260206000200160009055905550505050565b6000614fc883612139565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001830191839082156150845791602002820160005b8382111561505557835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302615017565b80156150825782816101000a81549060ff0219169055600101602081600001049283019260010302615055565b505b50611ce8929150615104565b82805461509c9061571d565b90600052602060002090601f0160209004810192826150be5760008555615084565b82601f106150d757805160ff1916838001178555615084565b82800160010185558215615084579182015b828111156150845782518255916020019190600101906150e9565b5b80821115611ce85760008155600101615105565b6001600160e01b031981168114613d5557600080fd5b60006020828403121561514157600080fd5b81356120a781615119565b60005b8381101561516757818101518382015260200161514f565b838111156133335750506000910152565b6000815180845261519081602086016020860161514c565b601f01601f19169290920160200192915050565b6020815260006120a76020830184615178565b8015158114613d5557600080fd5b60008060008061040085870312156151dc57600080fd5b8435935060e08501868111156151f157600080fd5b6020860193506103e086018781111561520957600080fd5b90925035615216816151b7565b939692955090935050565b60006020828403121561523357600080fd5b5035919050565b80356001600160a01b038116811461525157600080fd5b919050565b6000806040838503121561526957600080fd5b6152728361523a565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156152ba576152ba615280565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156152e9576152e9615280565b604052919050565b6000806000806080858703121561530757600080fd5b6153108561523a565b9350602061531f81870161523a565b935060408601359250606086013567ffffffffffffffff8082111561534357600080fd5b818801915088601f83011261535757600080fd5b81358181111561536957615369615280565b61537b601f8201601f191685016152c0565b9150808252898482850101111561539157600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000602082840312156153c357600080fd5b6120a78261523a565b6000806000606084860312156153e157600080fd5b6153ea8461523a565b92506153f86020850161523a565b9150604084013590509250925092565b60008060006060848603121561541d57600080fd5b83359250602084013561542f816151b7565b9150604084013561543f816151b7565b809150509250925092565b600082601f83011261545b57600080fd5b8135602067ffffffffffffffff82111561547757615477615280565b8160051b6154868282016152c0565b92835284810182019282810190878511156154a057600080fd5b83870192505b848310156154bf578235825291830191908301906154a6565b979650505050505050565b6000602082840312156154dc57600080fd5b813567ffffffffffffffff8111156154f357600080fd5b6115d08482850161544a565b6020808252825182820181905260009190848201906040850190845b818110156155375783518352928401929184019160010161551b565b50909695505050505050565b6000806040838503121561555657600080fd5b82359150602083013567ffffffffffffffff81111561557457600080fd5b6155808582860161544a565b9150509250929050565b8035600081900b811461525157600080fd5b600060405161030080820182811067ffffffffffffffff821117156155c3576155c3615280565b60405290915081908301848111156155da57600080fd5b835b818110156155fb576155ed8161558a565b8352602092830192016155dc565b50505092915050565b60008060006103e0848603121561561a57600080fd5b83359250602085603f86011261562f57600080fd5b60405160c0810181811067ffffffffffffffff8211171561565257615652615280565b6040528060e087018881111561566757600080fd5b8388015b818110156156895761567c8161558a565b835291840191840161566b565b508295508860ff89011261569c57600080fd5b6156a6898261559c565b9450505050509250925092565b600080604083850312156156c657600080fd5b6156cf8361523a565b915060208301356156df816151b7565b809150509250929050565b600080604083850312156156fd57600080fd5b6157068361523a565b91506157146020840161523a565b90509250929050565b600181811c9082168061573157607f821691505b602082108114156118f157634e487b7160e01b600052602260045260246000fd5b60006020828403121561576457600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082198211156157aa576157aa615781565b500190565b60006000198214156157c3576157c3615781565b5060010190565b6000828210156157dc576157dc615781565b500390565b6000602082840312156157f357600080fd5b81516120a7816151b7565b600081600019048311821515161561581857615818615781565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826158425761584261581d565b500490565b600060ff821660ff84168060ff0382111561586457615864615781565b019392505050565b805460ff8082168452600882901c81166020850152601082901c81166040850152601882901c811660608501526158ad60808501828460201c1660ff169052565b6158c160a08501828460281c1660ff169052565b6158d560c08501828460301c1660ff169052565b6158e960e08501828460381c1660ff169052565b6158fe6101008501828460401c1660ff169052565b6159136101208501828460481c1660ff169052565b6159286101408501828460501c1660ff169052565b61593d6101608501828460581c1660ff169052565b6159526101808501828460601c1660ff169052565b6159676101a08501828460681c1660ff169052565b61597c6101c08501828460701c1660ff169052565b6159916101e08501828460781c1660ff169052565b6159a66102008501828460801c1660ff169052565b6159bb6102208501828460881c1660ff169052565b6159d06102408501828460901c1660ff169052565b6159e56102608501828460981c1660ff169052565b6159fa6102808501828460a01c1660ff169052565b615a0f6102a08501828460a81c1660ff169052565b615a246102c08501828460b01c1660ff169052565b615a396102e08501828460b81c1660ff169052565b615a4e6103008501828460c01c1660ff169052565b615a636103208501828460c81c1660ff169052565b615a786103408501828460d01c1660ff169052565b615a8d6103608501828460d81c1660ff169052565b615aa26103808501828460e01c1660ff169052565b6133336103a08501828460e81c1660ff169052565b615acd82615ac6835460ff1690565b60ff169052565b615add602083016001830161586c565b600281015460ff81166103e0840152600881901c60ff16610400840152601081901c60ff16610420840152601881901c60ff16610440840152506003810154610460830152600481015461048083015260058101546104a083015260068101546104c0830152600701546104e090910152565b6108c08101615b5f8286615ab7565b61050082018460005b6006811015615b9257615b7a8261558a565b60000b83526020928301929190910190600101615b68565b5050506105c082018360005b6018811015615bc857615bb08261558a565b60000b83526020928301929190910190600101615b9e565b505050949350505050565b805160ff8116811461525157600080fd5b600082601f830112615bf557600080fd5b6040516103c080820182811067ffffffffffffffff82111715615c1a57615c1a615280565b60405283018185821115615c2d57600080fd5b845b82811015615c4e57615c4081615bd3565b825260209182019101615c2f565b509195945050505050565b60006105008284031215615c6c57600080fd5b615c74615296565b615c7d83615bd3565b8152615c8c8460208501615be4565b6020820152615c9e6103e08401615bd3565b6040820152615cb06104008401615bd3565b6060820152615cc26104208401615bd3565b6080820152615cd46104408401615bd3565b60a082015261046083015160c082015261048083015160e08201526104a08301516101008201526104c08301516101208201526104e09092015161014083015250919050565b600060208284031215615d2c57600080fd5b6120a782615bd3565b6105408101615d448286615ab7565b92151561050082015290151561052090910152919050565b61050081016107f28284615ab7565b6103e08101818560005b6006811015615d9757815160000b835260209283019290910190600101615d75565b50505060c082018460005b6018811015615dc457815160000b835260209283019290910190600101615da2565b505050826103c0830152949350505050565b60008251615de881846020870161514c565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000920191825250600501919050565b60008351615e2981846020880161514c565b835190830190615e3d81836020880161514c565b01949350505050565b600082615e5557615e5561581d565b500690565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612a8b6080830184615178565b600060208284031215615e9e57600080fd5b81516120a781615119565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d5e0afc7f66d75c69b90d46f1c258f2084287f3ad6b79f27bb2dd207b55549c164736f6c634300080900330000000000000000000000004f67c51b188497341e54238983e6cdbd635ee39b00000000000000000000000053773317d0442b631bebf820f407fe04ec63dc6c0000000000000000000000001061e9d1a2510af74e6b715abf17021f9818140e
Deployed Bytecode
0x608060405234801561001057600080fd5b50600436106103625760003560e01c806370a08231116101c85780639f6c2a8d11610104578063e949a9c0116100a2578063f2fde38b1161007c578063f2fde38b1461079b578063f658518a146107ae578063fe1b70c2146107c1578063fe829e87146107d457600080fd5b8063e949a9c01461076c578063e985e9c514610775578063ec9c4a431461078857600080fd5b8063c0011eec116100de578063c0011eec14610736578063c84c180b1461073e578063c87b56dd14610751578063cdb5415d1461076457600080fd5b80639f6c2a8d146106fd578063a22cb46514610710578063b88d4fde1461072357600080fd5b80638456cb59116101715780638da5cb5b1161014b5780638da5cb5b146106c457806395d89b41146106da5780639d13ac13146106e25780639e90f9aa146106f557600080fd5b80638456cb59146106a257806387e1aede146106aa5780638ad6dfdf146106bd57600080fd5b80638117b67a116101a25780638117b67a14610669578063836387101461067c578063844cb9f01461068f57600080fd5b806370a082311461063b578063715018a61461064e578063776e8eee1461065657600080fd5b8063379607f5116102a25780635aa4470f11610240578063616306ee1161021a578063616306ee146105495780636352211e1461055c578063640f845d1461056f5780636bf696991461057857600080fd5b80635aa4470f146105185780635c975abb1461052b5780635ec434981461053657600080fd5b80634610a32a1161027c5780634610a32a146104ca5780634d90769b146104df5780634f6ccce7146104f257806355de33431461050557600080fd5b8063379607f51461049c5780633f4ba83a146104af57806342842e0e146104b757600080fd5b8063176ce0f51161030f57806323b872dd116102e957806323b872dd146104505780632738e8061461046357806328c77820146104765780632f745c591461048957600080fd5b8063176ce0f51461042357806318160ddd1461043657806318b8cb991461044857600080fd5b8063081812fc11610340578063081812fc146103b9578063095ea7b3146103e4578063150b7a02146103f757600080fd5b806301ffc9a71461036757806306fdde031461038f57806307c20c8f146103a4575b600080fd5b61037a61037536600461512f565b6107e7565b60405190151581526020015b60405180910390f35b6103976107f8565b60405161038691906151a4565b6103b76103b23660046151c5565b61088a565b005b6103cc6103c7366004615221565b61141c565b6040516001600160a01b039091168152602001610386565b6103b76103f2366004615256565b6114b1565b61040a6104053660046152f1565b6115c7565b6040516001600160e01b03199091168152602001610386565b6103b76104313660046153b1565b6115d8565b6008545b604051908152602001610386565b61043a61165a565b6103b761045e3660046153cc565b611735565b61043a610471366004615408565b6117bc565b61043a6104843660046154ca565b611857565b61043a610497366004615256565b6118f7565b61043a6104aa366004615221565b61199f565b6103b7611ba3565b6103b76104c53660046153cc565b611c0d565b6104d2611c28565b60405161038691906154ff565b6103b76104ed3660046153b1565b611cec565b61043a610500366004615221565b611d6e565b6103b7610513366004615221565b611e12565b6103b76105263660046153b1565b611f97565b600b5460ff1661037a565b61043a610544366004615221565b612019565b600f546103cc906001600160a01b031681565b6103cc61056a366004615221565b6120ae565b61043a60135481565b6105df610586366004615221565b6000908152600e6020526040902080546002820154600383015460048401546005850154600686015460079096015460ff9586169761010086048716976201000087048816976301000000880481169716959493929091565b6040805160ff9b8c168152998b1660208b0152978a169789019790975297909416606087015262ffffff909216608086015260a085015260c084015260e083015261010082019290925261012081019190915261014001610386565b61043a6106493660046153b1565b612139565b6103b76121d3565b6011546103cc906001600160a01b031681565b6103b76106773660046153b1565b61223d565b6103cc61068a366004615221565b612448565b61043a61069d366004615221565b612453565b6103b7612508565b6103b76106b8366004615543565b612570565b600161043a565b600b5461010090046001600160a01b03166103cc565b610397612859565b61043a6106f0366004615604565b612868565b61043a600181565b6103b761070b366004615221565b612a95565b6103b761071e3660046156b3565b6131e6565b6103b76107313660046152f1565b6132ab565b6103b7613339565b61043a61074c366004615221565b61396c565b61039761075f366004615221565b613b86565b61043a613b91565b61043a60125481565b61037a6107833660046156ea565b613c13565b6010546103cc906001600160a01b031681565b6103b76107a93660046153b1565b613c70565b6103cc6107bc366004615221565b613d58565b61043a6107cf366004615221565b613d63565b61043a6107e2366004615221565b613daa565b60006107f282613fc8565b92915050565b6060600080546108079061571d565b80601f01602080910402602001604051908101604052809291908181526020018280546108339061571d565b80156108805780601f1061085557610100808354040283529160200191610880565b820191906000526020600020905b81548152906001019060200180831161086357829003601f168201915b5050505050905090565b83610894816120ae565b6001600160a01b0316336001600160a01b0316146108e85760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064015b60405180910390fd5b600b5460ff161561092e5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000610989868660068060200260405190810160405280929190826006602002808284376000920191909152505060408051610300818101909252915088906018908390839080828437600092019190915250612868915050565b601054604051631398fee160e31b8152600481018990529192506060916000916001600160a01b031690639cc7f7089060240160206040518083038186803b1580156109d457600080fd5b505afa1580156109e8573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610a0c9190615752565b90508415610b1057610a1c611c28565b915060005b8251811015610b0e5788838281518110610a3d57610a3d61576b565b60200260200101511415610a5057610afc565b60105483516001600160a01b0390911690639cc7f70890859084908110610a7957610a7961576b565b60200260200101516040518263ffffffff1660e01b8152600401610a9f91815260200190565b60206040518083038186803b158015610ab757600080fd5b505afa158015610acb573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610aef9190615752565b610af99083615797565b91505b80610b06816157af565b915050610a21565b505b82811015610b605760405162461bcd60e51b815260206004820152601a60248201527f596f7520646f206e6f74206861766520656e6f75676820474f4f00000000000060448201526064016108df565b6010546040516319942df560e31b8152600481018a9052600160248201526000916001600160a01b03169063cca16fa89060440160206040518083038186803b158015610bac57600080fd5b505afa158015610bc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610be49190615752565b905083811015610c365760405162461bcd60e51b815260206004820152601660248201527f796f75206e65656420676f6f20616c6c6f77616e63650000000000000000000060448201526064016108df565b838615610f1657601054604051631398fee160e31b8152600481018c90526000916001600160a01b031690639cc7f7089060240160206040518083038186803b158015610c8257600080fd5b505afa158015610c96573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cba9190615752565b905081811015610f1457610cce81836157ca565b915060005b8551811015610f06578b868281518110610cef57610cef61576b565b60200260200101511415610d0257610ef4565b6000868281518110610d1657610d1661576b565b6020908102919091010151601054604051631398fee160e31b8152600481018390529192506000916001600160a01b0390911690639cc7f7089060240160206040518083038186803b158015610d6b57600080fd5b505afa158015610d7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610da39190615752565b905084811015610e5257601054604051638856f77960e01b8152600160048201819052602482018590526044820152606481018390526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015610e0857600080fd5b505af1158015610e1c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e4091906157e1565b50610e4b81866157ca565b9450610ef1565b601054604051638856f77960e01b8152600160048201819052602482018590526044820152606481018790526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015610ead57600080fd5b505af1158015610ec1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ee591906157e1565b50600094505050610f06565b50505b80610efe816157af565b915050610cd3565b50610f118183615797565b91505b505b601054604051638856f77960e01b8152600160048201819052602482018d90526044820152606481018390526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015610f7157600080fd5b505af1158015610f85573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fa991906157e1565b506010546011546040805163096cf85d60e01b815290516001600160a01b039384169363b390c0ab93600193606493919092169163096cf85d916004808301926020929190829003018186803b15801561100257600080fd5b505afa158015611016573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061103a9190615752565b611044908a6157fe565b61104e9190615833565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561108c57600080fd5b505af11580156110a0573d6000803e3d6000fd5b50505060008b8152600e60205260409020600280820180549293506001929091906110d590849062010000900460ff16615847565b825460ff9182166101009390930a92830291909202199091161790555060115460405163420bfa6160e11b81526000916001600160a01b031690638417f4c2906111279085908f908f90600401615b50565b602060405180830381600087803b15801561114157600080fd5b505af1158015611155573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906111799190615752565b604051634a7dd52360e01b81526004810182905290915060009073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b1580156111cb57600080fd5b505af41580156111df573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112039190615c59565b61014081018e90526011546040808301519051632942467960e11b815260ff90911660048201529192506001600160a01b0316906352848cf290602401602060405180830381600087803b15801561125a57600080fd5b505af115801561126e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112929190615d1a565b60ff1660608201526011546040805163aacc5a1760e01b815290516001600160a01b039092169163aacc5a179160048082019260009290919082900301818387803b1580156112e057600080fd5b505af11580156112f4573d6000803e3d6000fd5b5050505060c08101829052600061130a33613fed565b6000818152600e602090815260409091208451815460ff191660ff909116178155908401519192508391611344906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c080850151600385015560e08501516004850155908401516005840155610120840151600684015561014090930151600790920191909155908301519051339083907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a45050505050505050505050505050565b6000818152600260205260408120546001600160a01b03166114955760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108df565b506000908152600460205260409020546001600160a01b031690565b60006114bc826120ae565b9050806001600160a01b0316836001600160a01b0316141561152a5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016108df565b336001600160a01b038216148061154657506115468133613c13565b6115b85760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016108df565b6115c28383614043565b505050565b630a85bd0160e11b5b949350505050565b600b546001600160a01b036101009091041633146116385760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b600080611665611c28565b905060005b81518110156117305760105482516001600160a01b0390911690639cc7f7089084908490811061169c5761169c61576b565b60200260200101516040518263ffffffff1660e01b81526004016116c291815260200190565b60206040518083038186803b1580156116da57600080fd5b505afa1580156116ee573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117129190615752565b61171c9084615797565b925080611728816157af565b91505061166a565b505090565b61173f33826140b1565b6117b15760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016108df565b6115c2838383614180565b6000838152600e60205260408082206011549151630aac6d3b60e31b815290916001600160a01b03169063556369d8906117fe90849088908890600401615d35565b60206040518083038186803b15801561181657600080fd5b505afa15801561182a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061184e9190615752565b95945050505050565b6000611865600b5460ff1690565b156118a55760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b60005b82518110156118f1576118d38382815181106118c6576118c661576b565b602002602001015161199f565b6118dd9083615797565b9150806118e9816157af565b9150506118a8565b50919050565b600061190283612139565b82106119765760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016108df565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6000816119ab816120ae565b6001600160a01b0316336001600160a01b0316146119fa5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff1615611a405760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000838152600e6020526040902060028101546301000000900460ff1615611aaa5760405162461bcd60e51b815260206004820152601960248201527f5370656369616c7320646f206e6f74206d616b6520474f4f210000000000000060448201526064016108df565b61012c816006015442611abd91906157ca565b11611b0a5760405162461bcd60e51b815260206004820152601160248201527f436c61696d206f6e20636f6f6c646f776e00000000000000000000000000000060448201526064016108df565b611b1384612019565b925042816006018190555082816005016000828254611b329190615797565b9091555050601054604051630d9778e560e11b815260048101869052602481018590526001600160a01b0390911690631b2ef1ca90604401600060405180830381600087803b158015611b8457600080fd5b505af1158015611b98573d6000803e3d6000fd5b505050505050919050565b600b546001600160a01b03610100909104163314611c035760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b611c0b61433f565b565b6115c2838383604051806020016040528060008152506132ab565b60606000611c3533612139565b905080611c5057505060408051600081526020810190915290565b60008167ffffffffffffffff811115611c6b57611c6b615280565b604051908082528060200260200182016040528015611c94578160200160208202803683370190505b50905060005b82811015611ce1576000611cae33836118f7565b905080838381518110611cc357611cc361576b565b60209081029190910101525080611cd9816157af565b915050611c9a565b5092915050565b5090565b600b546001600160a01b03610100909104163314611d4c5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b6000611d7960085490565b8210611ded5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016108df565b60088281548110611e0057611e0061576b565b90600052602060002001549050919050565b80611e1c816120ae565b6001600160a01b0316336001600160a01b031614611e6b5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff1615611eb15760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000828152600e6020526040812090611ec984613daa565b6013549091504290611ede9062093a80615797565b8110611eea5760006012555b60068301819055601254611f0357601282905560138190555b6010546040516390dd262760e01b81526001600482015260248101879052604481018490526001600160a01b03909116906390dd262790606401602060405180830381600087803b158015611f5757600080fd5b505af1158015611f6b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f8f91906157e1565b505050505050565b600b546001600160a01b03610100909104163314611ff75760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000818152600e6020526040808220601154915163c93d78ef60e01b815290916001600160a01b03169063c93d78ef90612057908490600401615d5c565b60206040518083038186803b15801561206f57600080fd5b505afa158015612083573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120a79190615752565b9392505050565b6000818152600260205260408120546001600160a01b0316806107f25760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016108df565b60006001600160a01b0382166121b75760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016108df565b506001600160a01b031660009081526003602052604090205490565b600b546001600160a01b036101009091041633146122335760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b611c0b60006143db565b600b546001600160a01b0361010090910416331461229d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b604051634a7dd52360e01b81526000600482018190529073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b1580156122ec57600080fd5b505af4158015612300573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906123249190615c59565b600160a08201529050600061233883613fed565b6000818152600e602090815260409091208451815460ff191660ff909116178155908401519192508391612372906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c080850151600385015560e085015160048501559084015160058401556101208401516006840155610140909301516007909201919091559083015190516001600160a01b0385169083907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a4505050565b60006107f2826120ae565b6000818152600e60205260408082206011549151630aac6d3b60e31b8152909183916001600160a01b039091169063556369d89061249990859085908190600401615d35565b60206040518083038186803b1580156124b157600080fd5b505afa1580156124c5573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124e99190615752565b6124f490605a6157fe565b90506115d081670de0b6b3a76400006157fe565b600b546001600160a01b036101009091041633146125685760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b611c0b61444c565b8161257a816120ae565b6001600160a01b0316336001600160a01b0316146125c95760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff161561260f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000838152600e6020526040902060028101546301000000900460ff16156126795760405162461bcd60e51b815260206004820152601460248201527f5370656369616c732063616e6e6f742041706f7000000000000000000000000060448201526064016108df565b60648160050154116126d95760405162461bcd60e51b815260206004820152602360248201527f4275646479206d7573742070726f64756365206174206c656173742031303020604482015262474f4f60e81b60648201526084016108df565b60006126e485613d63565b905060005b845181101561284457858582815181106127055761270561576b565b6020026020010151141561271857612832565b600085828151811061272c5761272c61576b565b60200260200101519050600061274182612453565b9050808411156127c357601054604051630d9778e560e11b815260048101839052602481018490526001600160a01b0390911690631b2ef1ca90604401600060405180830381600087803b15801561279857600080fd5b505af11580156127ac573d6000803e3d6000fd5b5050505080846127bc91906157ca565b935061282f565b601054604051630d9778e560e11b815260048101869052602481018490526001600160a01b0390911690631b2ef1ca90604401600060405180830381600087803b15801561281057600080fd5b505af1158015612824573d6000803e3d6000fd5b505050505050612844565b50505b8061283c816157af565b9150506126e9565b506128523361dead87611735565b5050505050565b6060600180546108079061571d565b6000838152600e6020526040812060028101546301000000900460ff16156128d25760405162461bcd60e51b815260206004820152601960248201527f5370656369616c732063616e6e6f74205265706c69636174650000000000000060448201526064016108df565b600281015460ff610100820481166201000090920416106129275760405162461bcd60e51b815260206004820152600f60248201526e213ab2323c9034b9903130b93932b760891b60448201526064016108df565b601160009054906101000a90046001600160a01b03166001600160a01b031663dcaf4fe36040518163ffffffff1660e01b815260040160206040518083038186803b15801561297557600080fd5b505afa158015612989573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ad9190615d1a565b600282015460ff9182169116106129f75760405162461bcd60e51b815260206004820152600e60248201526d26a0ac1023a2a722a920aa24a7a760911b60448201526064016108df565b6000612a0686600060016117bc565b60115460405163bb1dd8fd60e01b81529192506001600160a01b03169063bb1dd8fd90612a3b90889088908690600401615d6b565b60206040518083038186803b158015612a5357600080fd5b505afa158015612a67573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a8b9190615752565b9695505050505050565b80612a9f816120ae565b6001600160a01b0316336001600160a01b031614612aee5760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b60448201526064016108df565b600b5460ff1615612b345760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6000612b3f8361396c565b601054604051631398fee160e31b8152600481018690529192506000916001600160a01b0390911690639cc7f7089060240160206040518083038186803b158015612b8957600080fd5b505afa158015612b9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612bc19190615752565b905081811015612c135760405162461bcd60e51b815260206004820152601960248201527f796f75206e65656420676f6f20746f207265706c69636174650000000000000060448201526064016108df565b6010546040516319942df560e31b815260048101869052600160248201526000916001600160a01b03169063cca16fa89060440160206040518083038186803b158015612c5f57600080fd5b505afa158015612c73573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c979190615752565b905082811015612ce95760405162461bcd60e51b815260206004820152601660248201527f796f75206e65656420676f6f20616c6c6f77616e63650000000000000000000060448201526064016108df565b601054604051638856f77960e01b8152600160048201819052602482018890526044820152606481018590526001600160a01b0390911690638856f77990608401602060405180830381600087803b158015612d4457600080fd5b505af1158015612d58573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612d7c91906157e1565b506010546011546040805163096cf85d60e01b815290516001600160a01b039384169363b390c0ab93600193606493919092169163096cf85d916004808301926020929190829003018186803b158015612dd557600080fd5b505afa158015612de9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612e0d9190615752565b612e1790886157fe565b612e219190615833565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b158015612e5f57600080fd5b505af1158015612e73573d6000803e3d6000fd5b5050506000868152600e6020526040902060028082018054929350600192909190612ea890849062010000900460ff16615847565b825460ff9182166101009390930a9283029190920219909116179055506011546040516308ea004360e41b81526000916001600160a01b031690638ea0043090612ef6908590600401615d5c565b602060405180830381600087803b158015612f1057600080fd5b505af1158015612f24573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f489190615752565b604051634a7dd52360e01b81526004810182905290915060009073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b158015612f9a57600080fd5b505af4158015612fae573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612fd29190615c59565b61014081018990526011546040808301519051632942467960e11b815260ff90911660048201529192506001600160a01b0316906352848cf290602401602060405180830381600087803b15801561302957600080fd5b505af115801561303d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130619190615d1a565b60ff1660608201526011546040805163aacc5a1760e01b815290516001600160a01b039092169163aacc5a179160048082019260009290919082900301818387803b1580156130af57600080fd5b505af11580156130c3573d6000803e3d6000fd5b5050505060c0810182905260006130d933613fed565b6000818152600e602090815260409091208451815460ff191660ff909116178155908401519192508391613113906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c080850151600385015560e08501516004850155908401516005840155610120840151600684015561014090930151600790920191909155908301519051339083907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a4505050505050505050565b6001600160a01b03821633141561323f5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016108df565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6132b533836140b1565b6133275760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016108df565b613333848484846144c7565b50505050565b600b5460ff161561337f5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b600f546040516370a0823160e01b81523360048201526000916001600160a01b0316906370a082319060240160206040518083038186803b1580156133c357600080fd5b505afa1580156133d7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906133fb9190615752565b9050670de0b6b3a76400008110156134555760405162461bcd60e51b815260206004820152601960248201527f796f75206e656564206e616e6f20746f206275792067656e300000000000000060448201526064016108df565b600f54604051636eb1769f60e11b81523360048201523060248201526000916001600160a01b03169063dd62ed3e9060440160206040518083038186803b15801561349f57600080fd5b505afa1580156134b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906134d79190615752565b9050670de0b6b3a76400008110156135315760405162461bcd60e51b815260206004820152601860248201527f796f75206e656564206e616e6f20616c6c6f77616e636520000000000000000060448201526064016108df565b600b61353b614545565b11806135685750600b5461010090046001600160a01b03166001600160a01b0316336001600160a01b0316145b6135b45760405162461bcd60e51b815260206004820152601a60248201527f596f75206d757374207761697420666f7220666f756e6465727300000000000060448201526064016108df565b600f546040516323b872dd60e01b815233600482015261dead6024820152670de0b6b3a764000060448201526001600160a01b03909116906323b872dd90606401602060405180830381600087803b15801561360f57600080fd5b505af1158015613623573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061364791906157e1565b50600061365333613fed565b601154604051631a9caab960e01b8152600481018390529192506000916001600160a01b0390911690631a9caab990602401602060405180830381600087803b15801561369f57600080fd5b505af11580156136b3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906136d79190615752565b604051634a7dd52360e01b81526004810182905290915060009073c0770e1978916ed43bf762ac00b0e1341ad30c7890634a7dd523906024016105006040518083038186803b15801561372957600080fd5b505af415801561373d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906137619190615c59565b9050600b831161377357600260a08201525b6000838152600e602090815260409091208251815460ff191660ff909116178155908201518291906137ab906001830190601e615001565b506040828101516002830180546060860151608087015160a088015160ff95861661ffff199094169390931761010092861683021763ffff00001916620100009186169190910263ff0000001916176301000000949092169390930217905560c0840151600384015560e0840151600480850191909155908401516005840155610120840151600684015561014090930151600790920191909155601054601154825163f13060e960e01b815292516001600160a01b0392831694631b2ef1ca9489949093169263f13060e99281830192602092829003018186803b15801561389357600080fd5b505afa1580156138a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906138cb9190615752565b6138dd90670de0b6b3a76400006157fe565b6040516001600160e01b031960e085901b16815260048101929092526024820152604401600060405180830381600087803b15801561391b57600080fd5b505af115801561392f573d6000803e3d6000fd5b5050505060c0810151604051339085907fdec4c55cfb28350d52de9c956e1e0418e3c15f99b92c58f3bda111a0e646c70590600090a45050505050565b6000818152600e6020526040812060028101546301000000900460ff16156139d65760405162461bcd60e51b815260206004820152601960248201527f5370656369616c732063616e6e6f74205265706c69636174650000000000000060448201526064016108df565b600281015460ff61010082048116620100009092041610613a2b5760405162461bcd60e51b815260206004820152600f60248201526e213ab2323c9034b9903130b93932b760891b60448201526064016108df565b601160009054906101000a90046001600160a01b03166001600160a01b031663dcaf4fe36040518163ffffffff1660e01b815260040160206040518083038186803b158015613a7957600080fd5b505afa158015613a8d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613ab19190615d1a565b600282015460ff918216911610613afb5760405162461bcd60e51b815260206004820152600e60248201526d26a0ac1023a2a722a920aa24a7a760911b60448201526064016108df565b6000613b09846000806117bc565b60115460405163c84c180b60e01b8152600481018390529192506001600160a01b03169063c84c180b9060240160206040518083038186803b158015613b4e57600080fd5b505afa158015613b62573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115d09190615752565b60606107f282614550565b6011546040805163cdb5415d60e01b815290516000926001600160a01b03169163cdb5415d916004808301926020929190829003018186803b158015613bd657600080fd5b505afa158015613bea573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613c0e9190615752565b905090565b60006001600160a01b0382167358807bad0b376efc12f5ad86aac70e78ed67deae1415613c42575060016107f2565b6001600160a01b0380841660009081526005602090815260408083209386168352929052205460ff166120a7565b600b546001600160a01b03610100909104163314613cd05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016108df565b6001600160a01b038116613d4c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016108df565b613d55816143db565b50565b60006107f28261141c565b6000818152600e602052604080822060115460058201549251637f0db86160e11b815291926001600160a01b039091169163fe1b70c2916120579160040190815260200190565b6000818152600e602052604081206002808201546301000000900460ff1614613e155760405162461bcd60e51b815260206004820152600d60248201527f4e6f74206120466f756e6465720000000000000000000000000000000000000060448201526064016108df565b6006810154613e279062093a80615797565b421015613e765760405162461bcd60e51b815260206004820152601d60248201527f796f75206d7573742077616974206174206c656173742031207765656b00000060448201526064016108df565b6012541580613e945750601354613e909062093a80615797565b4210155b15613fbe5760006064601160009054906101000a90046001600160a01b03166001600160a01b031663096cf85d6040518163ffffffff1660e01b815260040160206040518083038186803b158015613eeb57600080fd5b505afa158015613eff573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613f239190615752565b613f2e9060646157ca565b601054604051631398fee160e31b8152600160048201526001600160a01b0390911690639cc7f7089060240160206040518083038186803b158015613f7257600080fd5b505afa158015613f86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613faa9190615752565b613fb491906157fe565b6115d09190615833565b5050601254919050565b60006001600160e01b0319821663780e9d6360e01b14806107f257506107f282614700565b600080613ff8614545565b90506140048382614750565b614035816140118361476e565b6040516020016140219190615dd6565b604051602081830303815290604052614884565b6107f2600c80546001019055565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190614078826120ae565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b031661412a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016108df565b6000614135836120ae565b9050806001600160a01b0316846001600160a01b031614806141705750836001600160a01b03166141658461141c565b6001600160a01b0316145b806115d057506115d08185613c13565b826001600160a01b0316614193826120ae565b6001600160a01b03161461420f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016108df565b6001600160a01b0382166142715760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016108df565b61427c83838361492d565b614287600082614043565b6001600160a01b03831660009081526003602052604081208054600192906142b09084906157ca565b90915550506001600160a01b03821660009081526003602052604081208054600192906142de908490615797565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600b5460ff166143915760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f742070617573656400000000000000000000000060448201526064016108df565b600b805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600b80546001600160a01b038381166101008181027fffffffffffffffffffffff0000000000000000000000000000000000000000ff85161790945560405193909204169182907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600b5460ff16156144925760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b600b805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586143be3390565b6144d2848484614180565b6144de8484848461497e565b6133335760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016108df565b6000613c0e600c5490565b6000818152600260205260409020546060906001600160a01b03166145dd5760405162461bcd60e51b815260206004820152603160248201527f45524337323155524953746f726167653a2055524920717565727920666f722060448201527f6e6f6e6578697374656e7420746f6b656e00000000000000000000000000000060648201526084016108df565b6000828152600a6020526040812080546145f69061571d565b80601f01602080910402602001604051908101604052809291908181526020018280546146229061571d565b801561466f5780601f106146445761010080835404028352916020019161466f565b820191906000526020600020905b81548152906001019060200180831161465257829003601f168201915b5050505050905060006146b260408051808201909152601c81527f68747470733a2f2f6170692e6d6963726f627564646965732e696f2f00000000602082015290565b90508051600014156146c5575092915050565b8151156146f75780826040516020016146df929190615e17565b60405160208183030381529060405292505050919050565b6115d084614ad3565b60006001600160e01b031982166380ac58cd60e01b148061473157506001600160e01b03198216635b5e139f60e01b145b806107f257506301ffc9a760e01b6001600160e01b03198316146107f2565b61476a828260405180602001604052806000815250614bed565b5050565b6060816147925750506040805180820190915260018152600360fc1b602082015290565b8160005b81156147bc57806147a6816157af565b91506147b59050600a83615833565b9150614796565b60008167ffffffffffffffff8111156147d7576147d7615280565b6040519080825280601f01601f191660200182016040528015614801576020820181803683370190505b5090505b84156115d0576148166001836157ca565b9150614823600a86615e46565b61482e906030615797565b60f81b8183815181106148435761484361576b565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535061487d600a86615833565b9450614805565b6000828152600260205260409020546001600160a01b031661490e5760405162461bcd60e51b815260206004820152602e60248201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60448201527f6578697374656e7420746f6b656e00000000000000000000000000000000000060648201526084016108df565b6000828152600a6020908152604090912082516115c292840190615090565b600b5460ff16156149735760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016108df565b6115c2838383614c6b565b60006001600160a01b0384163b15614acb57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906149c2903390899088908890600401615e5a565b602060405180830381600087803b1580156149dc57600080fd5b505af1925050508015614a0c575060408051601f3d908101601f19168201909252614a0991810190615e8c565b60015b614ab1573d808015614a3a576040519150601f19603f3d011682016040523d82523d6000602084013e614a3f565b606091505b508051614aa95760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016108df565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506115d0565b5060016115d0565b6000818152600260205260409020546060906001600160a01b0316614b605760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e000000000000000000000000000000000060648201526084016108df565b6000614b9c60408051808201909152601c81527f68747470733a2f2f6170692e6d6963726f627564646965732e696f2f00000000602082015290565b90506000815111614bbc57604051806020016040528060008152506120a7565b80614bc68461476e565b604051602001614bd7929190615e17565b6040516020818303038152906040529392505050565b614bf78383614d23565b614c04600084848461497e565b6115c25760405162461bcd60e51b815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b60648201526084016108df565b6001600160a01b038316614cc657614cc181600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b614ce9565b816001600160a01b0316836001600160a01b031614614ce957614ce98382614e71565b6001600160a01b038216614d00576115c281614f0e565b826001600160a01b0316826001600160a01b0316146115c2576115c28282614fbd565b6001600160a01b038216614d795760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016108df565b6000818152600260205260409020546001600160a01b031615614dde5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016108df565b614dea6000838361492d565b6001600160a01b0382166000908152600360205260408120805460019290614e13908490615797565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001614e7e84612139565b614e8891906157ca565b600083815260076020526040902054909150808214614edb576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090614f20906001906157ca565b60008381526009602052604081205460088054939450909284908110614f4857614f4861576b565b906000526020600020015490508060088381548110614f6957614f6961576b565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480614fa157614fa1615ea9565b6001900381819060005260206000200160009055905550505050565b6000614fc883612139565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001830191839082156150845791602002820160005b8382111561505557835183826101000a81548160ff021916908360ff1602179055509260200192600101602081600001049283019260010302615017565b80156150825782816101000a81549060ff0219169055600101602081600001049283019260010302615055565b505b50611ce8929150615104565b82805461509c9061571d565b90600052602060002090601f0160209004810192826150be5760008555615084565b82601f106150d757805160ff1916838001178555615084565b82800160010185558215615084579182015b828111156150845782518255916020019190600101906150e9565b5b80821115611ce85760008155600101615105565b6001600160e01b031981168114613d5557600080fd5b60006020828403121561514157600080fd5b81356120a781615119565b60005b8381101561516757818101518382015260200161514f565b838111156133335750506000910152565b6000815180845261519081602086016020860161514c565b601f01601f19169290920160200192915050565b6020815260006120a76020830184615178565b8015158114613d5557600080fd5b60008060008061040085870312156151dc57600080fd5b8435935060e08501868111156151f157600080fd5b6020860193506103e086018781111561520957600080fd5b90925035615216816151b7565b939692955090935050565b60006020828403121561523357600080fd5b5035919050565b80356001600160a01b038116811461525157600080fd5b919050565b6000806040838503121561526957600080fd5b6152728361523a565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051610160810167ffffffffffffffff811182821017156152ba576152ba615280565b60405290565b604051601f8201601f1916810167ffffffffffffffff811182821017156152e9576152e9615280565b604052919050565b6000806000806080858703121561530757600080fd5b6153108561523a565b9350602061531f81870161523a565b935060408601359250606086013567ffffffffffffffff8082111561534357600080fd5b818801915088601f83011261535757600080fd5b81358181111561536957615369615280565b61537b601f8201601f191685016152c0565b9150808252898482850101111561539157600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000602082840312156153c357600080fd5b6120a78261523a565b6000806000606084860312156153e157600080fd5b6153ea8461523a565b92506153f86020850161523a565b9150604084013590509250925092565b60008060006060848603121561541d57600080fd5b83359250602084013561542f816151b7565b9150604084013561543f816151b7565b809150509250925092565b600082601f83011261545b57600080fd5b8135602067ffffffffffffffff82111561547757615477615280565b8160051b6154868282016152c0565b92835284810182019282810190878511156154a057600080fd5b83870192505b848310156154bf578235825291830191908301906154a6565b979650505050505050565b6000602082840312156154dc57600080fd5b813567ffffffffffffffff8111156154f357600080fd5b6115d08482850161544a565b6020808252825182820181905260009190848201906040850190845b818110156155375783518352928401929184019160010161551b565b50909695505050505050565b6000806040838503121561555657600080fd5b82359150602083013567ffffffffffffffff81111561557457600080fd5b6155808582860161544a565b9150509250929050565b8035600081900b811461525157600080fd5b600060405161030080820182811067ffffffffffffffff821117156155c3576155c3615280565b60405290915081908301848111156155da57600080fd5b835b818110156155fb576155ed8161558a565b8352602092830192016155dc565b50505092915050565b60008060006103e0848603121561561a57600080fd5b83359250602085603f86011261562f57600080fd5b60405160c0810181811067ffffffffffffffff8211171561565257615652615280565b6040528060e087018881111561566757600080fd5b8388015b818110156156895761567c8161558a565b835291840191840161566b565b508295508860ff89011261569c57600080fd5b6156a6898261559c565b9450505050509250925092565b600080604083850312156156c657600080fd5b6156cf8361523a565b915060208301356156df816151b7565b809150509250929050565b600080604083850312156156fd57600080fd5b6157068361523a565b91506157146020840161523a565b90509250929050565b600181811c9082168061573157607f821691505b602082108114156118f157634e487b7160e01b600052602260045260246000fd5b60006020828403121561576457600080fd5b5051919050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b600082198211156157aa576157aa615781565b500190565b60006000198214156157c3576157c3615781565b5060010190565b6000828210156157dc576157dc615781565b500390565b6000602082840312156157f357600080fd5b81516120a7816151b7565b600081600019048311821515161561581857615818615781565b500290565b634e487b7160e01b600052601260045260246000fd5b6000826158425761584261581d565b500490565b600060ff821660ff84168060ff0382111561586457615864615781565b019392505050565b805460ff8082168452600882901c81166020850152601082901c81166040850152601882901c811660608501526158ad60808501828460201c1660ff169052565b6158c160a08501828460281c1660ff169052565b6158d560c08501828460301c1660ff169052565b6158e960e08501828460381c1660ff169052565b6158fe6101008501828460401c1660ff169052565b6159136101208501828460481c1660ff169052565b6159286101408501828460501c1660ff169052565b61593d6101608501828460581c1660ff169052565b6159526101808501828460601c1660ff169052565b6159676101a08501828460681c1660ff169052565b61597c6101c08501828460701c1660ff169052565b6159916101e08501828460781c1660ff169052565b6159a66102008501828460801c1660ff169052565b6159bb6102208501828460881c1660ff169052565b6159d06102408501828460901c1660ff169052565b6159e56102608501828460981c1660ff169052565b6159fa6102808501828460a01c1660ff169052565b615a0f6102a08501828460a81c1660ff169052565b615a246102c08501828460b01c1660ff169052565b615a396102e08501828460b81c1660ff169052565b615a4e6103008501828460c01c1660ff169052565b615a636103208501828460c81c1660ff169052565b615a786103408501828460d01c1660ff169052565b615a8d6103608501828460d81c1660ff169052565b615aa26103808501828460e01c1660ff169052565b6133336103a08501828460e81c1660ff169052565b615acd82615ac6835460ff1690565b60ff169052565b615add602083016001830161586c565b600281015460ff81166103e0840152600881901c60ff16610400840152601081901c60ff16610420840152601881901c60ff16610440840152506003810154610460830152600481015461048083015260058101546104a083015260068101546104c0830152600701546104e090910152565b6108c08101615b5f8286615ab7565b61050082018460005b6006811015615b9257615b7a8261558a565b60000b83526020928301929190910190600101615b68565b5050506105c082018360005b6018811015615bc857615bb08261558a565b60000b83526020928301929190910190600101615b9e565b505050949350505050565b805160ff8116811461525157600080fd5b600082601f830112615bf557600080fd5b6040516103c080820182811067ffffffffffffffff82111715615c1a57615c1a615280565b60405283018185821115615c2d57600080fd5b845b82811015615c4e57615c4081615bd3565b825260209182019101615c2f565b509195945050505050565b60006105008284031215615c6c57600080fd5b615c74615296565b615c7d83615bd3565b8152615c8c8460208501615be4565b6020820152615c9e6103e08401615bd3565b6040820152615cb06104008401615bd3565b6060820152615cc26104208401615bd3565b6080820152615cd46104408401615bd3565b60a082015261046083015160c082015261048083015160e08201526104a08301516101008201526104c08301516101208201526104e09092015161014083015250919050565b600060208284031215615d2c57600080fd5b6120a782615bd3565b6105408101615d448286615ab7565b92151561050082015290151561052090910152919050565b61050081016107f28284615ab7565b6103e08101818560005b6006811015615d9757815160000b835260209283019290910190600101615d75565b50505060c082018460005b6018811015615dc457815160000b835260209283019290910190600101615da2565b505050826103c0830152949350505050565b60008251615de881846020870161514c565b7f2e6a736f6e000000000000000000000000000000000000000000000000000000920191825250600501919050565b60008351615e2981846020880161514c565b835190830190615e3d81836020880161514c565b01949350505050565b600082615e5557615e5561581d565b500690565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612a8b6080830184615178565b600060208284031215615e9e57600080fd5b81516120a781615119565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220d5e0afc7f66d75c69b90d46f1c258f2084287f3ad6b79f27bb2dd207b55549c164736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000004f67c51b188497341e54238983e6cdbd635ee39b00000000000000000000000053773317d0442b631bebf820f407fe04ec63dc6c0000000000000000000000001061e9d1a2510af74e6b715abf17021f9818140e
-----Decoded View---------------
Arg [0] : _gooAddr (address): 0x4f67c51B188497341e54238983e6cdBD635eE39B
Arg [1] : _nanoFactoryAddr (address): 0x53773317d0442B631bebf820F407fE04ec63dC6c
Arg [2] : _buddyLogicAddr (address): 0x1061E9D1A2510aF74e6b715AbF17021f9818140E
-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 0000000000000000000000004f67c51b188497341e54238983e6cdbd635ee39b
Arg [1] : 00000000000000000000000053773317d0442b631bebf820f407fe04ec63dc6c
Arg [2] : 0000000000000000000000001061e9d1a2510af74e6b715abf17021f9818140e
[ 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.