ETH Price: $3,310.67 (-2.96%)
Gas: 19 Gwei

Token

Good Morning Cafe (GMOO)
 

Overview

Max Total Supply

333 GMOO

Holders

227

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 GMOO
0x56d41c5ea51c8081e3e52cf7ac2626d86ab70890
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

Chillest café in the metaverse. Succulent vibes. Art. Cowffee. Cowmmooonity.There will be 333 hand-drawn Highland Cows in this Good Morning Café 'Genesis' Collection. Each Moo in the Herd is lovingly created by Ben Colefax.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
GMOO

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 333 runs

Other Settings:
default evmVersion
File 1 of 8 : GMOO.sol
/*                              gweMBMEBBBMBMEBMBwg_.                                                           
                           aeMMEPP"  ' '. .  ..""^BMMBMe_'                             )BE   zEE .ZEEBL  JBBMg. 
                      __eEMPP .                     .`?RBEe,.                          $BM$_JMMBLJMEOEBL BEPEEE 
                    _BMMK'                              ''ME$L.                        $EEMEMBMB'5EE MMK$BE.]ME 
                  _BMB'                                    .$EE,   g@@BBBEEB.          5MB$EBEEE'MMK'MBKEME BEf 
  _eMBMMMEBM@g,,.zB$"                                         EBMMBBF``' .'EEk         MM('".]B$.EMKJBB BBL,EEP 
 JB$`. .. `?PKEMBEMBMEBg_                           _,we_      SBB.        ]ME        .BBP   $EE EMMME`.BBMMEK  
 $MP           .  . ``FBMe                          EEFEEE     .BEL       .$MK        .^^    1M   "F^.  .APP.   
 1BE'                   ^B$.                       JBB .BMK     JME      .BEK                                   
  1MB,                   [EE                        BB, 5B[     )E$    ,gBB`            .EEk                    
    BEB                 .BMP                        ?BEgME.    _BEBgLeMMBC_'          ,e$EM^                    
    .`MBMg,            gEBE'  ',,        eEBe,,,  . _@EEEE___e@MEPPPMEEMMMBBe         $MEP`                     
      ,BMBEMEew_L,_-wMBBR`    'RBMBewwBEBE"?PBBMEBMEER^`?RRMBM^`.  @e.    'BB.                                  
  __eBBP`''''^RRRBRRP`..        ..""YY`                     '.wgwL.'MBE  _wEE                                   
.@MBP`.                      Lgg_              _eMg.        JEBEMMe  3MMME$K                                    
$BP.                       JBBEBEB.           yBBBMBy       $EBMEBE   $ME.                                      
&EK_         .,            \MBEBBE.           "^   `.        '^R^ '   .BM'                                      
 `EEBBe@e@@BEMBK           ' RRK".                                     MB                                       
     BE$^YY"` .                                                       JM$                 https://www.gmcafe.io/
     ^".                                                              .*/
/// @author raffy.eth
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.15;

import {Ownable} from "@openzeppelin/[email protected]/access/Ownable.sol";
import {IERC165} from "@openzeppelin/[email protected]/utils/introspection/IERC165.sol";
import {IERC721} from "@openzeppelin/[email protected]/token/ERC721/IERC721.sol";
import {IERC1155} from "@openzeppelin/[email protected]/token/ERC1155/IERC1155.sol";
import {IERC721Metadata} from "@openzeppelin/[email protected]/token/ERC721/extensions/IERC721Metadata.sol";
import {IERC721Receiver} from "@openzeppelin/[email protected]/token/ERC721/IERC721Receiver.sol";

contract GMOO is Ownable, IERC165, IERC721, IERC721Metadata {

	function supportsInterface(bytes4 interfaceId) public pure returns (bool) {
		return interfaceId == type(IERC165).interfaceId // 0x01ffc9a7 
			|| interfaceId == type(IERC721).interfaceId // 0x80ac58cd
			|| interfaceId == type(IERC721Metadata).interfaceId; // 0x5b5e139f
	}

	error InvalidInput();
	error NotOpenSeaOwner(uint256 token); 
	error AlreadyMigrated(uint256 moo);
	error InvalidMoo(uint256 moo);
	error NotMooOperator(uint256 moo);
	error InvalidReceiver();
	error InvalidLockState();
	error NotAllowed();

	event MooLocked(uint256 moo);
	event MooUnlocked(uint256 moo);
	event MooUnlockAttempt(uint256 moo);

	uint256 constant HERD_SIZE = 333;
	address constant BURN_ADDRESS = 0x000000000000000000000000000000000000dEaD;
	address constant OPENSEA_CONDUIT = 0x1E0049783F008A0085193E00003D00cd54003c71;
	IERC1155 constant OPENSEA_NFT = IERC1155(0x495f947276749Ce646f68AC8c248420045cb7b5e); 
	uint256 constant CLAIM_DELAY = 33 days;

	//               OWNER_SHIFT    =   0; // 0x000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF 
	uint256 constant BLOCK_SHIFT    = 160; // 0x0000000000000000FFFFFFFF0000000000000000000000000000000000000000
	uint256 constant TRANSFER_SHIFT = 192; // 0x00000000FFFFFFFF000000000000000000000000000000000000000000000000
	uint256 constant TAG_SHIFT      = 224; // 0x0000FFFF00000000000000000000000000000000000000000000000000000000
	uint256 constant MOO_SHIFT      = 240; // 0xFFFF000000000000000000000000000000000000000000000000000000000000
	uint256 constant LOCK_BIT       = 1 << 255;
	uint256 constant TAG_CLEAR      = ~(uint256(type(uint16).max) << TAG_SHIFT); 

	struct Unlock {
		bytes32 hash;  // hash of your password
		uint256 price; // recovery price you set
	}

	string public _provenance;
	string public _tokenURIPrefix = "https://api.gmcafe.io/metadata/gmoo/";
	string public _tokenURISuffix = ".json";
	uint256 public _claimableTime;

	uint256 _migrated;
	mapping (address => uint256) _balances; // owner -> owned
	mapping (uint256 => uint256) _moos;     //   moo -> packed data
	mapping (uint256 => Unlock)  _unlocks;  //   moo -> Unlock

	mapping (uint256 => address) _tokenApprovals;
	mapping (address => mapping(address => bool)) _operatorApprovals;

	function _requireValidMoo(uint256 moo) private pure {
		if (moo == 0 || moo > HERD_SIZE) revert InvalidMoo(moo);
	}

	function _requireApproval(address owner, uint256 moo) private view {
		if (owner != msg.sender && !isApprovedForAll(owner, msg.sender) && getApproved(moo) != msg.sender) {
			revert NotMooOperator(moo);
		}
	}

	constructor() {
		_claimableTime = block.timestamp + CLAIM_DELAY;
	}

	function name() public pure returns (string memory) {
		return "Good Morning Cafe";
	}
	function symbol() public pure returns (string memory) {
		return "GMOO";
	}
	function totalSupply() public view returns (uint256) {
		return _migrated;
	}

	// admin
	function withdraw() onlyOwner public {
		if (address(this).balance == 0) revert InvalidReceiver();
		payable(msg.sender).transfer(address(this).balance);
	}

	// metadata
	function setProvenance(string calldata s) onlyOwner public {
		_provenance = s;
	}
	function setTokenURIPrefix(string calldata s) onlyOwner public {
		_tokenURIPrefix = s;
	}
	function setTokenURISuffix(string calldata s) onlyOwner public {
		_tokenURISuffix = s;
	}
	function tokenURI(uint256 moo) public view returns (string memory uri) {
		_requireValidMoo(moo);
		bytes memory prefix = bytes(_tokenURIPrefix);
		bytes memory suffix = bytes(_tokenURISuffix);
		unchecked {
			uri = new string(prefix.length + suffix.length + 68); // 3 + 1 + 32 + 32
		}
		uint256 ptr;
		assembly {
			ptr := uri
		}
		ptr = _appendBytes(ptr, prefix);
		ptr = _appendInt(ptr, moo, 3, 10); // +3
		ptr = _appendBytes(ptr, suffix);
		uint256 data = _moos[moo];
		if (data != 0) {
			ptr = _appendBytes(ptr, "?"); // +1
			ptr = _appendInt(ptr, data >> 128, 32, 16); // +32
			ptr = _appendInt(ptr, data,        32, 16); // +32
		}
		assembly {
			mstore(uri, sub(ptr, uri)) // truncate
		}
	}
	function _appendBytes(uint256 ptr, bytes memory data) private pure returns (uint256 dst) {
		uint256 src;
		assembly {
			src := data
			dst := add(ptr, mload(data)) // truncate
		}
		while (ptr < dst) {
			assembly {
				ptr := add(ptr, 32)
				src := add(src, 32)
				mstore(ptr, mload(src))
			}
		}
	}
	function _appendInt(uint256 ptr, uint256 value, uint256 len, uint256 base) private pure returns (uint256 dst) {
		uint256 bits =  len << 3;
		uint256 buf;
		unchecked {
			for (uint256 i; i < bits; i += 8) {
				uint256 x = value % base;
				buf |= (x < 10 ? 48 + x : 87 + x) << i; // "0" => 48, ("a" - 10) => 87
				value /= base;
			}
		}
		assembly {
			dst := add(ptr, len)
			mstore(dst, or(shl(bits, mload(ptr)), buf)) 
		}
	}

	// getters
	function getHerd() public view returns (bytes32[] memory ret) {
		ret = new bytes32[](HERD_SIZE);
		uint256 ptr;
		assembly {
			ptr := ret
		}
		uint256 moo;
		while (moo < HERD_SIZE) {
			unchecked { 
				uint256 data = _moos[++moo];
				if (data == 0) continue;
				assembly {
					ptr := add(ptr, 32)
					mstore(ptr, data)
				}
			}
		}
		assembly {
			mstore(ret, shr(5, sub(ptr, ret))) // truncate
		}
	}
	function getMoo(uint256 moo) public view returns (
			address owner, uint32 transfers, uint32 block0, uint32 blocksHeld, 
			uint16 tag, bool isLocked, uint256 unlockPrice
	) {
		uint256 data = _moos[moo];
		owner = address(uint160(data));
		if (owner != address(0)) {
			transfers = uint32(data >> TRANSFER_SHIFT);
			block0 = uint32(data >> BLOCK_SHIFT);
			unchecked {
				blocksHeld = uint32(block.number - block0);
			}
			tag = uint16(data >> TAG_SHIFT);
			isLocked = _isLocked(data);
			if (isLocked) {
				unlockPrice = _unlocks[moo].price;
			}
		}
	}
	function getWallet(address owner) public view returns (uint256[] memory moos) {
		uint256 n = _balances[owner];
		if (n != 0) {
			moos = new uint256[](n);
			uint256 moo = HERD_SIZE; // go backwards so output sorted
			while (true) {
				unchecked {
					if (address(uint160(_moos[moo])) == owner) {
						moos[--n] = moo;
						if (n == 0) break;
					}
					moo--;
				}
			}
		}
	}
	function balanceOf(address owner) public view returns (uint256) {
		if (owner == address(0)) revert InvalidInput(); // ERC721
		return _balances[owner];
	}
	function ownerOf(uint256 moo) public view returns (address) {
		return address(uint160(_moos[moo]));
	}

	// locking
	function isMooLocked(uint256 moo) public view returns (bool) {
		return _isLocked(_moos[moo]);
	}
	function _isLocked(uint256 data) private pure returns (bool) {
		return (data & LOCK_BIT) != 0;
	}
	function makePasswordHash(uint256 moo, string memory password) pure public returns (bytes32) {
		return keccak256(abi.encodePacked(moo, password));
	}
	function lockMoo(uint256 moo, uint256 price, bytes32 hash) public {
		uint256 data = _moos[moo];
		if (_isLocked(data)) revert InvalidLockState(); // already locked
		_requireApproval(address(uint160(data)), moo);
		if (price != 0) { // password only applies when non-zero
			_unlocks[moo] = Unlock({hash: hash, price: price});
		}
		_moos[moo] = data | LOCK_BIT;
		emit MooLocked(moo);
	}
	function unlockMoo(uint256 moo, string memory password, address transfer) payable public {
		uint256 data = _moos[moo];
		if (!_isLocked(data)) revert InvalidLockState(); // not locked
		address owner = address(uint160(data));
		_requireApproval(owner, moo); 
		Unlock storage unlock = _unlocks[moo];
		if (unlock.price != 0) { // must satisfy one of the following:
			if (msg.value == 0) { // check password
				if (unlock.hash != makePasswordHash(moo, password)) { // wrong password
					emit MooUnlockAttempt(moo);
					return;
				}
			} else if (msg.value < unlock.price) { // check price
				revert InvalidLockState(); // not enough
			}
			delete unlock.price; // zero storage
			delete unlock.hash;
		}
		_moos[moo] = data ^ LOCK_BIT; // clear lock
		emit MooUnlocked(moo);
		if (transfer != address(0)) {
			safeTransferFrom(owner, transfer, moo, ''); // could be a contract
		}
	}
	function rescueMoo(uint256 moo) onlyOwner public {
		// if the moo was locked and the owner gave this contract approval,
		// admin can break the lock and obtain the moo
		uint256 data = _moos[moo];
		if (!_isLocked(data)) revert InvalidLockState(); // not locked
		address owner = address(uint160(data));
		if (!isApprovedForAll(owner, address(this)) && getApproved(moo) != address(this)) revert NotMooOperator(moo);
		delete _unlocks[moo]; // zero storage
		_moos[moo] = data ^ LOCK_BIT; // clear lock
		emit MooUnlocked(moo);
		if (owner != msg.sender) { 
			_approvedTransfer(owner, msg.sender, moo); 
		}
	}
	
	// tagging
	function setTag(uint256 moo, uint16 tag) public {
		uint256 data = _moos[moo];
		_requireApproval(address(uint160(data)), moo);
		_moos[moo] = (data & TAG_CLEAR) | (uint256(tag) << TAG_SHIFT);
	}

	// minting
	function _mint(uint256 moo) private {
		_moos[moo] = (moo << MOO_SHIFT) | (block.number << BLOCK_SHIFT) | uint160(msg.sender);
		emit Transfer(address(0), msg.sender, moo); 
	}
	function _addMinted(uint256 n) private {
		uint256 prior = _balances[msg.sender];
		unchecked {
			_balances[msg.sender] = prior + n;
			_migrated += n;
		}
		if (prior == 0) { // first moo migrated
			setApprovalForAll(OPENSEA_CONDUIT, true);
		}
	}

	// migration	
	function isMigrationApproved(address sender) public view returns (bool) {
		return OPENSEA_NFT.isApprovedForAll(sender, address(this));
	}
	function getMigratableTokens(address sender) public view returns (uint256[] memory tokens, uint256[] memory moos) {		
		tokens = new uint256[](HERD_SIZE);
		address[] memory owners = new address[](HERD_SIZE);
		unchecked {
			for (uint256 i; i < HERD_SIZE; i++) {
				owners[i] = sender;
				tokens[i] = _tokenFromCollectionIndex(i + 1);
			}
		}
		uint256[] memory balances = OPENSEA_NFT.balanceOfBatch(owners, tokens);
		uint256 n;
		unchecked {
			for (uint256 i; i < HERD_SIZE; i++) {
				if (balances[i] != 0) {
					tokens[n++] = tokens[i];
				}
			}
		}
		assembly {
			mstore(tokens, n) // truncate
		}
		moos = new uint256[](n);
		for (uint256 i; i < n; i++) {
			moos[i] = mooFromToken(tokens[i]);
		}
	}
	function migrateMoos(uint256[] calldata tokens) public {
		uint256 n = tokens.length;
		if (n == 0) revert InvalidInput();
		uint256[] memory balances = new uint256[](n);
		unchecked { 
			for (uint256 i; i < n; i++) {
				balances[i] = 1;
			}
		}
		OPENSEA_NFT.safeBatchTransferFrom(msg.sender, BURN_ADDRESS, tokens, balances, ''); 
		unchecked { 
			for (uint256 i; i < n; i++) {
				uint256 moo = mooFromToken(tokens[i]);
				if (_moos[moo] != 0) revert AlreadyMigrated(moo); 
				_mint(moo); 
			}
		}
		_addMinted(n);
	}

	function secondsUntilClaimable() public view returns (uint256) {
		unchecked {
			return block.timestamp >= _claimableTime ? 0 : _claimableTime - block.timestamp;
		}
	}	
	function claimUnmigratedMoos(uint256 limit) onlyOwner public {	
		if (secondsUntilClaimable() != 0) revert NotAllowed(); // time lock
		unchecked {
			uint256 max = HERD_SIZE - _migrated; // claimable
			if (max == 0) revert InvalidInput(); // nothing to claim
			if (limit == 0) limit = max; // claim all
			uint256 moo;
			uint256 n;
			while (moo < HERD_SIZE) {
				moo++;
				if (_moos[moo] != 0) continue;
				_mint(moo);
				if (++n == limit) break;
			}
			_addMinted(n);
		}
	}

	// transfer
	function safeTransferFrom(address from, address to, uint256 moo) public {
		safeTransferFrom(from, to, moo, '');
	}
	function safeTransferFrom(address from, address to, uint256 moo, bytes memory data) public {
		transferFrom(from, to, moo);
		if (to.code.length != 0) {
			try IERC721Receiver(to).onERC721Received(msg.sender, from, moo, data) returns (bytes4 ret) {
				if (ret != IERC721Receiver.onERC721Received.selector) {
					revert InvalidReceiver();
				}
			} catch (bytes memory reason) {
				if (reason.length == 0) {
					revert InvalidReceiver();
				} else {
					assembly {
						revert(add(reason, 32), mload(reason))
					}
				}
			}
		}
	}
	function transferFrom(address from, address to, uint256 moo) public {
		if (to == address(0)) revert InvalidReceiver(); // ERC721
		_requireApproval(from, moo);
		_approvedTransfer(from, to, moo);
	}
	function _approvedTransfer(address from, address to, uint256 moo) private {
		if (to == from) revert InvalidReceiver(); // block transfer to self
		uint256 data = _moos[moo];
		if (address(uint160(data)) != from) revert NotAllowed(); // moo is not owned by from
		require(!_isLocked(data), "Moo is Locked"); // use string because user-facing error
		delete _tokenApprovals[moo]; // clear token approval
		unchecked {
			uint256 transfers = uint32((data >> TRANSFER_SHIFT) + 1);
			_moos[moo] = (moo << MOO_SHIFT)     // moo number
				| (block.number << BLOCK_SHIFT) // current block height
				| (transfers << TRANSFER_SHIFT) // updated transfer count
				| uint160(to);                  // new owner
			_balances[from]--;
			_balances[to]++;
		}
		emit Transfer(from, to, moo);
	}

	// operator approvals
	function isApprovedForAll(address owner, address operator) public view returns (bool) {
		return _operatorApprovals[owner][operator];
	}
	function setApprovalForAll(address operator, bool approved) public {
		if (operator == msg.sender) revert NotAllowed(); // owner is always approved
		_operatorApprovals[msg.sender][operator] = approved;
		emit ApprovalForAll(msg.sender, operator, approved);
	}

	// token approvals
	function getApproved(uint256 moo) public view returns (address) {
		_requireValidMoo(moo); // ERC721
		return _tokenApprovals[moo];
	}
	function approve(address to, uint256 moo) public {
		address owner = address(uint160(_moos[moo]));
		if (owner != msg.sender && !isApprovedForAll(owner, msg.sender)) revert NotMooOperator(moo);
		_tokenApprovals[moo] = to;
		emit Approval(owner, to, moo);
	}

	// old token => new token
	function _tokenFromCollectionIndex(uint256 i) private pure returns (uint256) {
		//       |-------------------------------creator||-------index||--------|
		return 0xB3457C2065FD1F384E9F05495251F2894D1659B6000000000000000000000001 | (i << 40);
	}
	function mooFromToken(uint256 token) public pure returns (uint256) {
		uint256 index = uint16(token >> 40); // see above
		if (_tokenFromCollectionIndex(index) != token) revert InvalidInput(); // not a moo
		uint256 moo = _mooFromCollectionIndex(index);
		_requireValidMoo(moo); // weird shit bro
		return moo;
	}
	function _mooFromCollectionIndex(uint256 i) private pure returns (uint256) {
		unchecked {
			if (i <= 180) {
				if (i <= 99) {
					if (i <= 52) {
						if (i <= 29) {
							if (i <= 21) return i;
							if (i == 22) return 301;
							return i - 1;
						} else {
							if (i == 30) return 302;
							return i - 2;
						}
					} else {
						if (i <= 68) {
							if (i <= 54) return i + 1;
							if (i <= 57) return i - 4;
							return i - 2;
						} else {
							if (i == 69) return 303;
							return i - 3;
						}
					}
				} else {
					if (i <= 156) {
						if (i == 100) return 296;
						if (i == 136) return 133;
						if (i == 137) return 132;
						return i - 4;
					} else {
						if (i == 157) return 162;
						if (i == 167) return 248;
						return i - 5;
					}
				}
			} else {
				if (i <= 278) {
					if (i <= 253) {
						if (i <= 245) {
							if (i == 181) return 304;
							if (i == 245) return 305;
							return i - 6;
						} else {
							if (i == 253) return 306;
							return i - 7;
						}
					} else {
						if (i <= 255) return i - 8;
						if (i <= 274) return i - 7;
						if (i == 275) return 307;
						return i - 8;
					}
				} else {
					if (i <= 297) {
						if (i == 279) return 309;
						if (i == 286) return 288;
						if (i == 297) return 277;
						return i - 9;
					} else {
						if (i <= 304) return i - 9;
						if (i <= 308) return i - 8;
						if (i == 309) return 308;
						return i;
					}
				}
			}
		}
	}

}

File 2 of 8 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

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 `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

File 3 of 8 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

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);
}

File 4 of 8 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 5 of 8 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721.sol)

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`.
     *
     * 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;

    /**
     * @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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @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);
}

File 6 of 8 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

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);
}

File 7 of 8 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

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() {
        _transferOwnership(_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 {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 8 of 8 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

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;
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 333
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"AlreadyMigrated","type":"error"},{"inputs":[],"name":"InvalidInput","type":"error"},{"inputs":[],"name":"InvalidLockState","type":"error"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"InvalidMoo","type":"error"},{"inputs":[],"name":"InvalidReceiver","type":"error"},{"inputs":[],"name":"NotAllowed","type":"error"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"NotMooOperator","type":"error"},{"inputs":[{"internalType":"uint256","name":"token","type":"uint256"}],"name":"NotOpenSeaOwner","type":"error"},{"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":false,"internalType":"uint256","name":"moo","type":"uint256"}],"name":"MooLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"moo","type":"uint256"}],"name":"MooUnlockAttempt","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"moo","type":"uint256"}],"name":"MooUnlocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_claimableTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_provenance","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenURIPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenURISuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"moo","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":[{"internalType":"uint256","name":"limit","type":"uint256"}],"name":"claimUnmigratedMoos","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getHerd","outputs":[{"internalType":"bytes32[]","name":"ret","type":"bytes32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"getMigratableTokens","outputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"},{"internalType":"uint256[]","name":"moos","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"getMoo","outputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint32","name":"transfers","type":"uint32"},{"internalType":"uint32","name":"block0","type":"uint32"},{"internalType":"uint32","name":"blocksHeld","type":"uint32"},{"internalType":"uint16","name":"tag","type":"uint16"},{"internalType":"bool","name":"isLocked","type":"bool"},{"internalType":"uint256","name":"unlockPrice","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"getWallet","outputs":[{"internalType":"uint256[]","name":"moos","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":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"isMigrationApproved","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"isMooLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"},{"internalType":"uint256","name":"price","type":"uint256"},{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"lockMoo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"},{"internalType":"string","name":"password","type":"string"}],"name":"makePasswordHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokens","type":"uint256[]"}],"name":"migrateMoos","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"token","type":"uint256"}],"name":"mooFromToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"rescueMoo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"moo","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":"moo","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"secondsUntilClaimable","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"setProvenance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"},{"internalType":"uint16","name":"tag","type":"uint16"}],"name":"setTag","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"setTokenURIPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"s","type":"string"}],"name":"setTokenURISuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"uri","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":"moo","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"moo","type":"uint256"},{"internalType":"string","name":"password","type":"string"},{"internalType":"address","name":"transfer","type":"address"}],"name":"unlockMoo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e0604052602460808181529062002e6360a03960029062000022908262000175565b50604080518082019091526005815264173539b7b760d91b60208201526003906200004e908262000175565b503480156200005c57600080fd5b50620000683362000080565b62000077622b81804262000241565b60045562000268565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b634e487b7160e01b600052604160045260246000fd5b600181811c90821680620000fb57607f821691505b6020821081036200011c57634e487b7160e01b600052602260045260246000fd5b50919050565b601f8211156200017057600081815260208120601f850160051c810160208610156200014b5750805b601f850160051c820191505b818110156200016c5782815560010162000157565b5050505b505050565b81516001600160401b03811115620001915762000191620000d0565b620001a981620001a28454620000e6565b8462000122565b602080601f831160018114620001e15760008415620001c85750858301515b600019600386901b1c1916600185901b1785556200016c565b600085815260208120601f198616915b828110156200021257888601518255948401946001909101908401620001f1565b5085821015620002315787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b600082198211156200026357634e487b7160e01b600052601160045260246000fd5b500190565b612beb80620002786000396000f3fe60806040526004361061023b5760003560e01c8063835ec7ec1161012e578063bebc8810116100ab578063d76fdedb1161006f578063d76fdedb146106bf578063e985e9c51461072e578063e98e534d14610777578063f2fde38b146107a5578063ffe630b5146107c557600080fd5b8063bebc881014610635578063c0d7c9f514610655578063c87b56dd14610675578063cd2e7d4314610695578063d69714e7146106aa57600080fd5b80639dedf385116100f25780639dedf3851461059f578063a22cb465146105bf578063a9852bfb146105df578063aac54309146105ff578063b88d4fde1461061557600080fd5b8063835ec7ec146104f45780638da5cb5b1461051457806392c17ddd1461053257806395d89b411461055257806399e0dd7c1461057f57600080fd5b806342842e0e116101bc578063715018a611610180578063715018a6146104685780637c63820a1461047d5780637dc1fa291461049f5780638260c407146104bf5780638269846a146104df57600080fd5b806342842e0e146103c857806351071044146103e857806357956df5146103fb5780636352211e1461041b57806370a082311461044857600080fd5b80630c0b8ba3116102035780630c0b8ba31461033f57806318160ddd1461035457806323b872dd1461037357806336d0d5cb146103935780633ccfd60b146103b357600080fd5b806301ffc9a71461024057806304d0a6471461027557806306fdde03146102a2578063081812fc146102e5578063095ea7b31461031d575b600080fd5b34801561024c57600080fd5b5061026061025b366004612275565b6107e5565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b506102956102903660046122a9565b610837565b60405161026c91906122ff565b3480156102ae57600080fd5b50604080518082019091526011815270476f6f64204d6f726e696e67204361666560781b60208201525b60405161026c919061236a565b3480156102f157600080fd5b5061030561030036600461237d565b610900565b6040516001600160a01b03909116815260200161026c565b34801561032957600080fd5b5061033d610338366004612396565b610927565b005b34801561034b57600080fd5b506102d86109f5565b34801561036057600080fd5b506005545b60405190815260200161026c565b34801561037f57600080fd5b5061033d61038e3660046123c0565b610a83565b34801561039f57600080fd5b5061033d6103ae36600461237d565b610ac4565b3480156103bf57600080fd5b5061033d610bbb565b3480156103d457600080fd5b5061033d6103e33660046123c0565b610c53565b61033d6103f63660046124bb565b610c6e565b34801561040757600080fd5b5061036561041636600461237d565b610dd1565b34801561042757600080fd5b5061030561043636600461237d565b60009081526007602052604090205490565b34801561045457600080fd5b506103656104633660046122a9565b610e44565b34801561047457600080fd5b5061033d610e89565b34801561048957600080fd5b50610492610edd565b60405161026c9190612512565b3480156104ab57600080fd5b5061033d6104ba366004612556565b610f4b565b3480156104cb57600080fd5b506102606104da3660046122a9565b6110d8565b3480156104eb57600080fd5b5061036561115d565b34801561050057600080fd5b5061033d61050f3660046125cb565b611179565b34801561052057600080fd5b506000546001600160a01b0316610305565b34801561053e57600080fd5b5061033d61054d3660046125f7565b611242565b34801561055e57600080fd5b50604080518082019091526004815263474d4f4f60e01b60208201526102d8565b34801561058b57600080fd5b5061033d61059a36600461262e565b611289565b3480156105ab57600080fd5b506102606105ba36600461237d565b6112de565b3480156105cb57600080fd5b5061033d6105da36600461269c565b6112fa565b3480156105eb57600080fd5b5061033d6105fa36600461262e565b61138f565b34801561060b57600080fd5b5061036560045481565b34801561062157600080fd5b5061033d6106303660046126c8565b6113e4565b34801561064157600080fd5b5061033d61065036600461237d565b611502565b34801561066157600080fd5b50610365610670366004612744565b61165b565b34801561068157600080fd5b506102d861069036600461237d565b61168e565b3480156106a157600080fd5b506102d861189b565b3480156106b657600080fd5b506102d86118a8565b3480156106cb57600080fd5b506106df6106da36600461237d565b6118b5565b604080516001600160a01b03909816885263ffffffff96871660208901529486169487019490945293909116606085015261ffff16608084015290151560a083015260c082015260e00161026c565b34801561073a57600080fd5b5061026061074936600461278b565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b34801561078357600080fd5b506107976107923660046122a9565b61192b565b60405161026c9291906127be565b3480156107b157600080fd5b5061033d6107c03660046122a9565b611ba9565b3480156107d157600080fd5b5061033d6107e036600461262e565b611c5f565b60006001600160e01b031982166301ffc9a760e01b148061081657506001600160e01b031982166380ac58cd60e01b145b8061083157506001600160e01b03198216635b5e139f60e01b145b92915050565b6001600160a01b03811660009081526006602052604090205460609080156108fa578067ffffffffffffffff811115610872576108726123fc565b60405190808252806020026020018201604052801561089b578160200160208202803683370190505b50915061014d5b6000818152600760205260409020546001600160a01b038086169116036108ef5780838360019003935083815181106108dd576108dd6127ec565b602090810291909101015281156108f8575b600019016108a2565b505b50919050565b600061090b82611cb4565b506000908152600960205260409020546001600160a01b031690565b6000818152600760205260409020546001600160a01b038116331480159061097357506001600160a01b0381166000908152600a6020908152604080832033845290915290205460ff16155b156109995760405163f52d857560e01b8152600481018390526024015b60405180910390fd5b60008281526009602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60038054610a0290612802565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2e90612802565b8015610a7b5780601f10610a5057610100808354040283529160200191610a7b565b820191906000526020600020905b815481529060010190602001808311610a5e57829003601f168201915b505050505081565b6001600160a01b038216610aaa57604051631e4ec46b60e01b815260040160405180910390fd5b610ab48382611ce3565b610abf838383611d62565b505050565b6000546001600160a01b03163314610b0c5760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b610b1461115d565b15610b3257604051631eb49d6d60e11b815260040160405180910390fd5b60055461014d8190039061014c1901610b5e5760405163b4fa3fb360e01b815260040160405180910390fd5b81600003610b6a578091505b6000805b61014d821015610bac5760019091016000818152600760205260408120549192919003610b6e57610b9e82611ebe565b838160010191508103610b6e575b610bb581611f0a565b50505050565b6000546001600160a01b03163314610c035760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b47600003610c2457604051631e4ec46b60e01b815260040160405180910390fd5b60405133904780156108fc02916000818181858888f19350505050158015610c50573d6000803e3d6000fd5b50565b610abf838383604051806020016040528060008152506113e4565b600083815260076020526040902054600160ff1b8116610ca157604051630106530b60e21b815260040160405180910390fd5b80610cac8186611ce3565b6000858152600860205260409020600181015415610d4e5734600003610d1d57610cd6868661165b565b815414610d18576040518681527fa8c4fe1d64253b2119c9bce7ea6967216bb076f884db34297e6af465989b9ff79060200160405180910390a1505050505050565b610d42565b8060010154341015610d4257604051630106530b60e21b815260040160405180910390fd5b60006001820181905581555b60008681526007602052604090819020600160ff1b85189055517fbaca06dc89fc277a1113adb7c45566031562eb138b7d8e5cd141ea0cd4d62d7e90610d979088815260200190565b60405180910390a16001600160a01b03841615610dc957610dc9828588604051806020016040528060008152506113e4565b505050505050565b6000602882901c61ffff168266ffff000000000081167fb3457c2065fd1f384e9f05495251f2894d1659b60000000000000000000000011714610e275760405163b4fa3fb360e01b815260040160405180910390fd5b6000610e3282611f50565b9050610e3d81611cb4565b9392505050565b60006001600160a01b038216610e6d5760405163b4fa3fb360e01b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205490565b6000546001600160a01b03163314610ed15760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b610edb6000612174565b565b6040805161014d8082526129c08201909252606091602082016129a0803683370190505090508060005b61014d811015610f3f5760010160008181526007602052604081205490819003610f315750610f07565b602092909201918252610f07565b5081900360051c815290565b806000819003610f6e5760405163b4fa3fb360e01b815260040160405180910390fd5b60008167ffffffffffffffff811115610f8957610f896123fc565b604051908082528060200260200182016040528015610fb2578160200160208202803683370190505b50905060005b82811015610fe7576001828281518110610fd457610fd46127ec565b6020908102919091010152600101610fb8565b50604051631759616b60e11b815273495f947276749ce646f68ac8c248420045cb7b5e90632eb2c2d69061102990339061dead90899089908890600401612836565b600060405180830381600087803b15801561104357600080fd5b505af1158015611057573d6000803e3d6000fd5b5050505060005b828110156110ce57600061108986868481811061107d5761107d6127ec565b90506020020135610dd1565b600081815260076020526040902054909150156110bc5760405163f3103e1560e01b815260048101829052602401610990565b6110c581611ebe565b5060010161105e565b50610bb582611f0a565b60405163e985e9c560e01b81526001600160a01b038216600482015230602482015260009073495f947276749ce646f68ac8c248420045cb7b5e9063e985e9c590604401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083191906128ba565b6000600454421015611173574260045403905090565b50600090565b600083815260076020526040902054600160ff1b8116156111ad57604051630106530b60e21b815260040160405180910390fd5b6111b78185611ce3565b82156111eb576040805180820182528381526020808201868152600088815260089092529290209051815590516001909101555b60008481526007602052604090819020600160ff1b83179055517f10051dc77b72fdff1eccc560a200c24c60523f15b2a1800a99fe9275825c9137906112349086815260200190565b60405180910390a150505050565b60008281526007602052604090205461125b8184611ce3565b60009283526007602052604090922060e09190911b61ffff60e01b1661ffff60e01b19909216919091179055565b6000546001600160a01b031633146112d15760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6002610abf82848361291d565b600081815260076020526040812054600160ff1b161515610831565b336001600160a01b0383160361132357604051631eb49d6d60e11b815260040160405180910390fd5b336000818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000546001600160a01b031633146113d75760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6003610abf82848361291d565b6113ef848484610a83565b6001600160a01b0383163b15610bb557604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906114319033908890879087906004016129dd565b6020604051808303816000875af192505050801561146c575060408051601f3d908101601f1916820190925261146991810190612a19565b60015b6114ca573d80801561149a576040519150601f19603f3d011682016040523d82523d6000602084013e61149f565b606091505b5080516000036114c257604051631e4ec46b60e01b815260040160405180910390fd5b805160208201fd5b6001600160e01b03198116630a85bd0160e11b146114fb57604051631e4ec46b60e01b815260040160405180910390fd5b5050505050565b6000546001600160a01b0316331461154a5760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b600081815260076020526040902054600160ff1b811661157d57604051630106530b60e21b815260040160405180910390fd5b6001600160a01b0381166000908152600a60209081526040808320308452909152902054819060ff161580156115c45750306115b884610900565b6001600160a01b031614155b156115e55760405163f52d857560e01b815260048101849052602401610990565b60008381526008602090815260408083208381556001018390556007825291829020600160ff1b8518905590518481527fbaca06dc89fc277a1113adb7c45566031562eb138b7d8e5cd141ea0cd4d62d7e910160405180910390a16001600160a01b0381163314610abf57610abf813385611d62565b60008282604051602001611670929190612a36565b60405160208183030381529060405280519060200120905092915050565b606061169982611cb4565b6000600280546116a890612802565b80601f01602080910402602001604051908101604052809291908181526020018280546116d490612802565b80156117215780601f106116f657610100808354040283529160200191611721565b820191906000526020600020905b81548152906001019060200180831161170457829003601f168201915b5050505050905060006003805461173790612802565b80601f016020809104026020016040519081016040528092919081815260200182805461176390612802565b80156117b05780601f10611785576101008083540402835291602001916117b0565b820191906000526020600020905b81548152906001019060200180831161179357829003601f168201915b50505050509050805182510160440167ffffffffffffffff8111156117d7576117d76123fc565b6040519080825280601f01601f191660200182016040528015611801576020820181803683370190505b5092508261180f81846121c4565b905061181f81866003600a6121ec565b905061182b81836121c4565b600086815260076020526040902054909150801561188d5761186682604051806040016040528060018152602001603f60f81b8152506121c4565b915061187a82608083901c602060106121ec565b915061188a8282602060106121ec565b91505b848203855250505050919050565b60028054610a0290612802565b60018054610a0290612802565b600081815260076020526040812054908080808080866001600160a01b0381161561191f5760c081901c965060a081901c955063ffffffff86164303945060e081901c9350600160ff1b8116158015935061191f5760008981526008602052604090206001015491505b50919395979092949650565b6040805161014d8082526129c08201909252606091829190602082016129a08036833750506040805161014d8082526129c082019092529294506000929150602082016129a08036833701905050905060005b61014d811015611a01578482828151811061199b5761199b6127ec565b6001600160a01b03909216602092830291909101909101526001810160281b7fb3457c2065fd1f384e9f05495251f2894d1659b6000000000000000000000001178482815181106119ee576119ee6127ec565b602090810291909101015260010161197e565b506040516313849cfd60e21b815260009073495f947276749ce646f68ac8c248420045cb7b5e90634e1273f490611a3e9085908890600401612a5c565b600060405180830381865afa158015611a5b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a839190810190612ab2565b90506000805b61014d811015611afb57828181518110611aa557611aa56127ec565b6020026020010151600014611af357858181518110611ac657611ac66127ec565b6020026020010151868380600101945081518110611ae657611ae66127ec565b6020026020010181815250505b600101611a89565b508085528067ffffffffffffffff811115611b1857611b186123fc565b604051908082528060200260200182016040528015611b41578160200160208202803683370190505b50935060005b81811015611ba057611b71868281518110611b6457611b646127ec565b6020026020010151610dd1565b858281518110611b8357611b836127ec565b602090810291909101015280611b9881612b58565b915050611b47565b50505050915091565b6000546001600160a01b03163314611bf15760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6001600160a01b038116611c565760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610990565b610c5081612174565b6000546001600160a01b03163314611ca75760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6001610abf82848361291d565b801580611cc2575061014d81115b15610c5057604051635026910d60e01b815260048101829052602401610990565b6001600160a01b0382163314801590611d2057506001600160a01b0382166000908152600a6020908152604080832033845290915290205460ff16155b8015611d3d575033611d3182610900565b6001600160a01b031614155b15611d5e5760405163f52d857560e01b815260048101829052602401610990565b5050565b826001600160a01b0316826001600160a01b031603611d9457604051631e4ec46b60e01b815260040160405180910390fd5b6000818152600760205260409020546001600160a01b0380821690851614611dcf57604051631eb49d6d60e11b815260040160405180910390fd5b600160ff1b811615611e135760405162461bcd60e51b815260206004820152600d60248201526c135bdbc81a5cc8131bd8dad959609a1b6044820152606401610990565b600082815260096020908152604080832080546001600160a01b0319169055600782528083206001600160a01b0387811660c087811c600190810190911b63ffffffff60c01b164360a01b60f08b901b17178217909355908916808652600690945282852080546000190190558085528285208054909201909155905185939192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a450505050565b600081815260076020526040808220334360a01b60f086901b17811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450565b3360009081526006602052604081208054838101909155600580548401905590819003611d5e57611d5e731e0049783f008a0085193e00003d00cd54003c7160016112fa565b600060b482116120595760638211611ff05760348211611fb057601d8211611f975760158211611f7e575090565b81601603611f8f575061012d919050565b506000190190565b81601e03611fa8575061012e919050565b506001190190565b60448211611fd75760368211611fc7575060010190565b60398211611fa857506003190190565b81604503611fe8575061012f919050565b506002190190565b609c821161203157816064036120095750610128919050565b8160880361201957506085919050565b8160890361202957506084919050565b506003190190565b81609d03612041575060a2919050565b8160a703612051575060f8919050565b506004190190565b61011682116120f05760fd82116120b55760f5821161209c578160b5036120835750610130919050565b8160f5036120945750610131919050565b506005190190565b8160fd036120ad5750610132919050565b506006190190565b60ff82116120c557506007190190565b61011282116120d657506006190190565b81610113036120e85750610133919050565b506007190190565b610129821161213757816101170361210b5750610135919050565b8161011e0361211d5750610120919050565b816101290361212f5750610115919050565b506008190190565b610130821161214857506008190190565b610134821161215957506007190190565b816101350361216b5750610134919050565b5090565b919050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80518201815b818410156121e55760209081018051949091019384526121ca565b5092915050565b6000600383901b81805b8281101561224a57600085888161220f5761220f612b7f565b06905081600a82106122245781605701612229565b816030015b901b8317925085888161223e5761223e612b7f565b049750506008016121f6565b50865190911b17929094019182525092915050565b6001600160e01b031981168114610c5057600080fd5b60006020828403121561228757600080fd5b8135610e3d8161225f565b80356001600160a01b038116811461216f57600080fd5b6000602082840312156122bb57600080fd5b610e3d82612292565b600081518084526020808501945080840160005b838110156122f4578151875295820195908201906001016122d8565b509495945050505050565b602081526000610e3d60208301846122c4565b60005b8381101561232d578181015183820152602001612315565b83811115610bb55750506000910152565b60008151808452612356816020860160208601612312565b601f01601f19169290920160200192915050565b602081526000610e3d602083018461233e565b60006020828403121561238f57600080fd5b5035919050565b600080604083850312156123a957600080fd5b6123b283612292565b946020939093013593505050565b6000806000606084860312156123d557600080fd5b6123de84612292565b92506123ec60208501612292565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561243b5761243b6123fc565b604052919050565b600067ffffffffffffffff83111561245d5761245d6123fc565b612470601f8401601f1916602001612412565b905082815283838301111561248457600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124ac57600080fd5b610e3d83833560208501612443565b6000806000606084860312156124d057600080fd5b83359250602084013567ffffffffffffffff8111156124ee57600080fd5b6124fa8682870161249b565b92505061250960408501612292565b90509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561254a5783518352928401929184019160010161252e565b50909695505050505050565b6000806020838503121561256957600080fd5b823567ffffffffffffffff8082111561258157600080fd5b818501915085601f83011261259557600080fd5b8135818111156125a457600080fd5b8660208260051b85010111156125b957600080fd5b60209290920196919550909350505050565b6000806000606084860312156125e057600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561260a57600080fd5b82359150602083013561ffff8116811461262357600080fd5b809150509250929050565b6000806020838503121561264157600080fd5b823567ffffffffffffffff8082111561265957600080fd5b818501915085601f83011261266d57600080fd5b81358181111561267c57600080fd5b8660208285010111156125b957600080fd5b8015158114610c5057600080fd5b600080604083850312156126af57600080fd5b6126b883612292565b915060208301356126238161268e565b600080600080608085870312156126de57600080fd5b6126e785612292565b93506126f560208601612292565b925060408501359150606085013567ffffffffffffffff81111561271857600080fd5b8501601f8101871361272957600080fd5b61273887823560208401612443565b91505092959194509250565b6000806040838503121561275757600080fd5b82359150602083013567ffffffffffffffff81111561277557600080fd5b6127818582860161249b565b9150509250929050565b6000806040838503121561279e57600080fd5b6127a783612292565b91506127b560208401612292565b90509250929050565b6040815260006127d160408301856122c4565b82810360208401526127e381856122c4565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061281657607f821691505b6020821081036108fa57634e487b7160e01b600052602260045260246000fd5b6001600160a01b0386811682528516602082015260a060408201819052810183905260006001600160fb1b0384111561286e57600080fd5b8360051b808660c0850137808301905060c081016000815260c084830301606085015261289b81866122c4565b8481036080909501949094525050600082525060200195945050505050565b6000602082840312156128cc57600080fd5b8151610e3d8161268e565b601f821115610abf57600081815260208120601f850160051c810160208610156128fe5750805b601f850160051c820191505b81811015610dc95782815560010161290a565b67ffffffffffffffff831115612935576129356123fc565b612949836129438354612802565b836128d7565b6000601f84116001811461297d57600085156129655750838201355b600019600387901b1c1916600186901b1783556114fb565b600083815260209020601f19861690835b828110156129ae578685013582556020948501946001909201910161298e565b50868210156129cb5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612a0f608083018461233e565b9695505050505050565b600060208284031215612a2b57600080fd5b8151610e3d8161225f565b82815260008251612a4e816020850160208701612312565b919091016020019392505050565b604080825283519082018190526000906020906060840190828701845b82811015612a9e5781516001600160a01b031684529284019290840190600101612a79565b50505083810382850152612a0f81866122c4565b60006020808385031215612ac557600080fd5b825167ffffffffffffffff80821115612add57600080fd5b818501915085601f830112612af157600080fd5b815181811115612b0357612b036123fc565b8060051b9150612b14848301612412565b8181529183018401918481019088841115612b2e57600080fd5b938501935b83851015612b4c57845182529385019390850190612b33565b98975050505050505050565b600060018201612b7857634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052601260045260246000fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220ec2bd1c6bcd3828d379a4cccb828fc3d33d6b0b4c25a6589da7397be9ced88c364736f6c634300080f003368747470733a2f2f6170692e676d636166652e696f2f6d657461646174612f676d6f6f2f

Deployed Bytecode

0x60806040526004361061023b5760003560e01c8063835ec7ec1161012e578063bebc8810116100ab578063d76fdedb1161006f578063d76fdedb146106bf578063e985e9c51461072e578063e98e534d14610777578063f2fde38b146107a5578063ffe630b5146107c557600080fd5b8063bebc881014610635578063c0d7c9f514610655578063c87b56dd14610675578063cd2e7d4314610695578063d69714e7146106aa57600080fd5b80639dedf385116100f25780639dedf3851461059f578063a22cb465146105bf578063a9852bfb146105df578063aac54309146105ff578063b88d4fde1461061557600080fd5b8063835ec7ec146104f45780638da5cb5b1461051457806392c17ddd1461053257806395d89b411461055257806399e0dd7c1461057f57600080fd5b806342842e0e116101bc578063715018a611610180578063715018a6146104685780637c63820a1461047d5780637dc1fa291461049f5780638260c407146104bf5780638269846a146104df57600080fd5b806342842e0e146103c857806351071044146103e857806357956df5146103fb5780636352211e1461041b57806370a082311461044857600080fd5b80630c0b8ba3116102035780630c0b8ba31461033f57806318160ddd1461035457806323b872dd1461037357806336d0d5cb146103935780633ccfd60b146103b357600080fd5b806301ffc9a71461024057806304d0a6471461027557806306fdde03146102a2578063081812fc146102e5578063095ea7b31461031d575b600080fd5b34801561024c57600080fd5b5061026061025b366004612275565b6107e5565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b506102956102903660046122a9565b610837565b60405161026c91906122ff565b3480156102ae57600080fd5b50604080518082019091526011815270476f6f64204d6f726e696e67204361666560781b60208201525b60405161026c919061236a565b3480156102f157600080fd5b5061030561030036600461237d565b610900565b6040516001600160a01b03909116815260200161026c565b34801561032957600080fd5b5061033d610338366004612396565b610927565b005b34801561034b57600080fd5b506102d86109f5565b34801561036057600080fd5b506005545b60405190815260200161026c565b34801561037f57600080fd5b5061033d61038e3660046123c0565b610a83565b34801561039f57600080fd5b5061033d6103ae36600461237d565b610ac4565b3480156103bf57600080fd5b5061033d610bbb565b3480156103d457600080fd5b5061033d6103e33660046123c0565b610c53565b61033d6103f63660046124bb565b610c6e565b34801561040757600080fd5b5061036561041636600461237d565b610dd1565b34801561042757600080fd5b5061030561043636600461237d565b60009081526007602052604090205490565b34801561045457600080fd5b506103656104633660046122a9565b610e44565b34801561047457600080fd5b5061033d610e89565b34801561048957600080fd5b50610492610edd565b60405161026c9190612512565b3480156104ab57600080fd5b5061033d6104ba366004612556565b610f4b565b3480156104cb57600080fd5b506102606104da3660046122a9565b6110d8565b3480156104eb57600080fd5b5061036561115d565b34801561050057600080fd5b5061033d61050f3660046125cb565b611179565b34801561052057600080fd5b506000546001600160a01b0316610305565b34801561053e57600080fd5b5061033d61054d3660046125f7565b611242565b34801561055e57600080fd5b50604080518082019091526004815263474d4f4f60e01b60208201526102d8565b34801561058b57600080fd5b5061033d61059a36600461262e565b611289565b3480156105ab57600080fd5b506102606105ba36600461237d565b6112de565b3480156105cb57600080fd5b5061033d6105da36600461269c565b6112fa565b3480156105eb57600080fd5b5061033d6105fa36600461262e565b61138f565b34801561060b57600080fd5b5061036560045481565b34801561062157600080fd5b5061033d6106303660046126c8565b6113e4565b34801561064157600080fd5b5061033d61065036600461237d565b611502565b34801561066157600080fd5b50610365610670366004612744565b61165b565b34801561068157600080fd5b506102d861069036600461237d565b61168e565b3480156106a157600080fd5b506102d861189b565b3480156106b657600080fd5b506102d86118a8565b3480156106cb57600080fd5b506106df6106da36600461237d565b6118b5565b604080516001600160a01b03909816885263ffffffff96871660208901529486169487019490945293909116606085015261ffff16608084015290151560a083015260c082015260e00161026c565b34801561073a57600080fd5b5061026061074936600461278b565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205460ff1690565b34801561078357600080fd5b506107976107923660046122a9565b61192b565b60405161026c9291906127be565b3480156107b157600080fd5b5061033d6107c03660046122a9565b611ba9565b3480156107d157600080fd5b5061033d6107e036600461262e565b611c5f565b60006001600160e01b031982166301ffc9a760e01b148061081657506001600160e01b031982166380ac58cd60e01b145b8061083157506001600160e01b03198216635b5e139f60e01b145b92915050565b6001600160a01b03811660009081526006602052604090205460609080156108fa578067ffffffffffffffff811115610872576108726123fc565b60405190808252806020026020018201604052801561089b578160200160208202803683370190505b50915061014d5b6000818152600760205260409020546001600160a01b038086169116036108ef5780838360019003935083815181106108dd576108dd6127ec565b602090810291909101015281156108f8575b600019016108a2565b505b50919050565b600061090b82611cb4565b506000908152600960205260409020546001600160a01b031690565b6000818152600760205260409020546001600160a01b038116331480159061097357506001600160a01b0381166000908152600a6020908152604080832033845290915290205460ff16155b156109995760405163f52d857560e01b8152600481018390526024015b60405180910390fd5b60008281526009602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b60038054610a0290612802565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2e90612802565b8015610a7b5780601f10610a5057610100808354040283529160200191610a7b565b820191906000526020600020905b815481529060010190602001808311610a5e57829003601f168201915b505050505081565b6001600160a01b038216610aaa57604051631e4ec46b60e01b815260040160405180910390fd5b610ab48382611ce3565b610abf838383611d62565b505050565b6000546001600160a01b03163314610b0c5760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b610b1461115d565b15610b3257604051631eb49d6d60e11b815260040160405180910390fd5b60055461014d8190039061014c1901610b5e5760405163b4fa3fb360e01b815260040160405180910390fd5b81600003610b6a578091505b6000805b61014d821015610bac5760019091016000818152600760205260408120549192919003610b6e57610b9e82611ebe565b838160010191508103610b6e575b610bb581611f0a565b50505050565b6000546001600160a01b03163314610c035760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b47600003610c2457604051631e4ec46b60e01b815260040160405180910390fd5b60405133904780156108fc02916000818181858888f19350505050158015610c50573d6000803e3d6000fd5b50565b610abf838383604051806020016040528060008152506113e4565b600083815260076020526040902054600160ff1b8116610ca157604051630106530b60e21b815260040160405180910390fd5b80610cac8186611ce3565b6000858152600860205260409020600181015415610d4e5734600003610d1d57610cd6868661165b565b815414610d18576040518681527fa8c4fe1d64253b2119c9bce7ea6967216bb076f884db34297e6af465989b9ff79060200160405180910390a1505050505050565b610d42565b8060010154341015610d4257604051630106530b60e21b815260040160405180910390fd5b60006001820181905581555b60008681526007602052604090819020600160ff1b85189055517fbaca06dc89fc277a1113adb7c45566031562eb138b7d8e5cd141ea0cd4d62d7e90610d979088815260200190565b60405180910390a16001600160a01b03841615610dc957610dc9828588604051806020016040528060008152506113e4565b505050505050565b6000602882901c61ffff168266ffff000000000081167fb3457c2065fd1f384e9f05495251f2894d1659b60000000000000000000000011714610e275760405163b4fa3fb360e01b815260040160405180910390fd5b6000610e3282611f50565b9050610e3d81611cb4565b9392505050565b60006001600160a01b038216610e6d5760405163b4fa3fb360e01b815260040160405180910390fd5b506001600160a01b031660009081526006602052604090205490565b6000546001600160a01b03163314610ed15760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b610edb6000612174565b565b6040805161014d8082526129c08201909252606091602082016129a0803683370190505090508060005b61014d811015610f3f5760010160008181526007602052604081205490819003610f315750610f07565b602092909201918252610f07565b5081900360051c815290565b806000819003610f6e5760405163b4fa3fb360e01b815260040160405180910390fd5b60008167ffffffffffffffff811115610f8957610f896123fc565b604051908082528060200260200182016040528015610fb2578160200160208202803683370190505b50905060005b82811015610fe7576001828281518110610fd457610fd46127ec565b6020908102919091010152600101610fb8565b50604051631759616b60e11b815273495f947276749ce646f68ac8c248420045cb7b5e90632eb2c2d69061102990339061dead90899089908890600401612836565b600060405180830381600087803b15801561104357600080fd5b505af1158015611057573d6000803e3d6000fd5b5050505060005b828110156110ce57600061108986868481811061107d5761107d6127ec565b90506020020135610dd1565b600081815260076020526040902054909150156110bc5760405163f3103e1560e01b815260048101829052602401610990565b6110c581611ebe565b5060010161105e565b50610bb582611f0a565b60405163e985e9c560e01b81526001600160a01b038216600482015230602482015260009073495f947276749ce646f68ac8c248420045cb7b5e9063e985e9c590604401602060405180830381865afa158015611139573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061083191906128ba565b6000600454421015611173574260045403905090565b50600090565b600083815260076020526040902054600160ff1b8116156111ad57604051630106530b60e21b815260040160405180910390fd5b6111b78185611ce3565b82156111eb576040805180820182528381526020808201868152600088815260089092529290209051815590516001909101555b60008481526007602052604090819020600160ff1b83179055517f10051dc77b72fdff1eccc560a200c24c60523f15b2a1800a99fe9275825c9137906112349086815260200190565b60405180910390a150505050565b60008281526007602052604090205461125b8184611ce3565b60009283526007602052604090922060e09190911b61ffff60e01b1661ffff60e01b19909216919091179055565b6000546001600160a01b031633146112d15760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6002610abf82848361291d565b600081815260076020526040812054600160ff1b161515610831565b336001600160a01b0383160361132357604051631eb49d6d60e11b815260040160405180910390fd5b336000818152600a602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000546001600160a01b031633146113d75760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6003610abf82848361291d565b6113ef848484610a83565b6001600160a01b0383163b15610bb557604051630a85bd0160e11b81526001600160a01b0384169063150b7a02906114319033908890879087906004016129dd565b6020604051808303816000875af192505050801561146c575060408051601f3d908101601f1916820190925261146991810190612a19565b60015b6114ca573d80801561149a576040519150601f19603f3d011682016040523d82523d6000602084013e61149f565b606091505b5080516000036114c257604051631e4ec46b60e01b815260040160405180910390fd5b805160208201fd5b6001600160e01b03198116630a85bd0160e11b146114fb57604051631e4ec46b60e01b815260040160405180910390fd5b5050505050565b6000546001600160a01b0316331461154a5760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b600081815260076020526040902054600160ff1b811661157d57604051630106530b60e21b815260040160405180910390fd5b6001600160a01b0381166000908152600a60209081526040808320308452909152902054819060ff161580156115c45750306115b884610900565b6001600160a01b031614155b156115e55760405163f52d857560e01b815260048101849052602401610990565b60008381526008602090815260408083208381556001018390556007825291829020600160ff1b8518905590518481527fbaca06dc89fc277a1113adb7c45566031562eb138b7d8e5cd141ea0cd4d62d7e910160405180910390a16001600160a01b0381163314610abf57610abf813385611d62565b60008282604051602001611670929190612a36565b60405160208183030381529060405280519060200120905092915050565b606061169982611cb4565b6000600280546116a890612802565b80601f01602080910402602001604051908101604052809291908181526020018280546116d490612802565b80156117215780601f106116f657610100808354040283529160200191611721565b820191906000526020600020905b81548152906001019060200180831161170457829003601f168201915b5050505050905060006003805461173790612802565b80601f016020809104026020016040519081016040528092919081815260200182805461176390612802565b80156117b05780601f10611785576101008083540402835291602001916117b0565b820191906000526020600020905b81548152906001019060200180831161179357829003601f168201915b50505050509050805182510160440167ffffffffffffffff8111156117d7576117d76123fc565b6040519080825280601f01601f191660200182016040528015611801576020820181803683370190505b5092508261180f81846121c4565b905061181f81866003600a6121ec565b905061182b81836121c4565b600086815260076020526040902054909150801561188d5761186682604051806040016040528060018152602001603f60f81b8152506121c4565b915061187a82608083901c602060106121ec565b915061188a8282602060106121ec565b91505b848203855250505050919050565b60028054610a0290612802565b60018054610a0290612802565b600081815260076020526040812054908080808080866001600160a01b0381161561191f5760c081901c965060a081901c955063ffffffff86164303945060e081901c9350600160ff1b8116158015935061191f5760008981526008602052604090206001015491505b50919395979092949650565b6040805161014d8082526129c08201909252606091829190602082016129a08036833750506040805161014d8082526129c082019092529294506000929150602082016129a08036833701905050905060005b61014d811015611a01578482828151811061199b5761199b6127ec565b6001600160a01b03909216602092830291909101909101526001810160281b7fb3457c2065fd1f384e9f05495251f2894d1659b6000000000000000000000001178482815181106119ee576119ee6127ec565b602090810291909101015260010161197e565b506040516313849cfd60e21b815260009073495f947276749ce646f68ac8c248420045cb7b5e90634e1273f490611a3e9085908890600401612a5c565b600060405180830381865afa158015611a5b573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611a839190810190612ab2565b90506000805b61014d811015611afb57828181518110611aa557611aa56127ec565b6020026020010151600014611af357858181518110611ac657611ac66127ec565b6020026020010151868380600101945081518110611ae657611ae66127ec565b6020026020010181815250505b600101611a89565b508085528067ffffffffffffffff811115611b1857611b186123fc565b604051908082528060200260200182016040528015611b41578160200160208202803683370190505b50935060005b81811015611ba057611b71868281518110611b6457611b646127ec565b6020026020010151610dd1565b858281518110611b8357611b836127ec565b602090810291909101015280611b9881612b58565b915050611b47565b50505050915091565b6000546001600160a01b03163314611bf15760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6001600160a01b038116611c565760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610990565b610c5081612174565b6000546001600160a01b03163314611ca75760405162461bcd60e51b81526020600482018190526024820152600080516020612b968339815191526044820152606401610990565b6001610abf82848361291d565b801580611cc2575061014d81115b15610c5057604051635026910d60e01b815260048101829052602401610990565b6001600160a01b0382163314801590611d2057506001600160a01b0382166000908152600a6020908152604080832033845290915290205460ff16155b8015611d3d575033611d3182610900565b6001600160a01b031614155b15611d5e5760405163f52d857560e01b815260048101829052602401610990565b5050565b826001600160a01b0316826001600160a01b031603611d9457604051631e4ec46b60e01b815260040160405180910390fd5b6000818152600760205260409020546001600160a01b0380821690851614611dcf57604051631eb49d6d60e11b815260040160405180910390fd5b600160ff1b811615611e135760405162461bcd60e51b815260206004820152600d60248201526c135bdbc81a5cc8131bd8dad959609a1b6044820152606401610990565b600082815260096020908152604080832080546001600160a01b0319169055600782528083206001600160a01b0387811660c087811c600190810190911b63ffffffff60c01b164360a01b60f08b901b17178217909355908916808652600690945282852080546000190190558085528285208054909201909155905185939192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a450505050565b600081815260076020526040808220334360a01b60f086901b17811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a450565b3360009081526006602052604081208054838101909155600580548401905590819003611d5e57611d5e731e0049783f008a0085193e00003d00cd54003c7160016112fa565b600060b482116120595760638211611ff05760348211611fb057601d8211611f975760158211611f7e575090565b81601603611f8f575061012d919050565b506000190190565b81601e03611fa8575061012e919050565b506001190190565b60448211611fd75760368211611fc7575060010190565b60398211611fa857506003190190565b81604503611fe8575061012f919050565b506002190190565b609c821161203157816064036120095750610128919050565b8160880361201957506085919050565b8160890361202957506084919050565b506003190190565b81609d03612041575060a2919050565b8160a703612051575060f8919050565b506004190190565b61011682116120f05760fd82116120b55760f5821161209c578160b5036120835750610130919050565b8160f5036120945750610131919050565b506005190190565b8160fd036120ad5750610132919050565b506006190190565b60ff82116120c557506007190190565b61011282116120d657506006190190565b81610113036120e85750610133919050565b506007190190565b610129821161213757816101170361210b5750610135919050565b8161011e0361211d5750610120919050565b816101290361212f5750610115919050565b506008190190565b610130821161214857506008190190565b610134821161215957506007190190565b816101350361216b5750610134919050565b5090565b919050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b80518201815b818410156121e55760209081018051949091019384526121ca565b5092915050565b6000600383901b81805b8281101561224a57600085888161220f5761220f612b7f565b06905081600a82106122245781605701612229565b816030015b901b8317925085888161223e5761223e612b7f565b049750506008016121f6565b50865190911b17929094019182525092915050565b6001600160e01b031981168114610c5057600080fd5b60006020828403121561228757600080fd5b8135610e3d8161225f565b80356001600160a01b038116811461216f57600080fd5b6000602082840312156122bb57600080fd5b610e3d82612292565b600081518084526020808501945080840160005b838110156122f4578151875295820195908201906001016122d8565b509495945050505050565b602081526000610e3d60208301846122c4565b60005b8381101561232d578181015183820152602001612315565b83811115610bb55750506000910152565b60008151808452612356816020860160208601612312565b601f01601f19169290920160200192915050565b602081526000610e3d602083018461233e565b60006020828403121561238f57600080fd5b5035919050565b600080604083850312156123a957600080fd5b6123b283612292565b946020939093013593505050565b6000806000606084860312156123d557600080fd5b6123de84612292565b92506123ec60208501612292565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f1916810167ffffffffffffffff8111828210171561243b5761243b6123fc565b604052919050565b600067ffffffffffffffff83111561245d5761245d6123fc565b612470601f8401601f1916602001612412565b905082815283838301111561248457600080fd5b828260208301376000602084830101529392505050565b600082601f8301126124ac57600080fd5b610e3d83833560208501612443565b6000806000606084860312156124d057600080fd5b83359250602084013567ffffffffffffffff8111156124ee57600080fd5b6124fa8682870161249b565b92505061250960408501612292565b90509250925092565b6020808252825182820181905260009190848201906040850190845b8181101561254a5783518352928401929184019160010161252e565b50909695505050505050565b6000806020838503121561256957600080fd5b823567ffffffffffffffff8082111561258157600080fd5b818501915085601f83011261259557600080fd5b8135818111156125a457600080fd5b8660208260051b85010111156125b957600080fd5b60209290920196919550909350505050565b6000806000606084860312156125e057600080fd5b505081359360208301359350604090920135919050565b6000806040838503121561260a57600080fd5b82359150602083013561ffff8116811461262357600080fd5b809150509250929050565b6000806020838503121561264157600080fd5b823567ffffffffffffffff8082111561265957600080fd5b818501915085601f83011261266d57600080fd5b81358181111561267c57600080fd5b8660208285010111156125b957600080fd5b8015158114610c5057600080fd5b600080604083850312156126af57600080fd5b6126b883612292565b915060208301356126238161268e565b600080600080608085870312156126de57600080fd5b6126e785612292565b93506126f560208601612292565b925060408501359150606085013567ffffffffffffffff81111561271857600080fd5b8501601f8101871361272957600080fd5b61273887823560208401612443565b91505092959194509250565b6000806040838503121561275757600080fd5b82359150602083013567ffffffffffffffff81111561277557600080fd5b6127818582860161249b565b9150509250929050565b6000806040838503121561279e57600080fd5b6127a783612292565b91506127b560208401612292565b90509250929050565b6040815260006127d160408301856122c4565b82810360208401526127e381856122c4565b95945050505050565b634e487b7160e01b600052603260045260246000fd5b600181811c9082168061281657607f821691505b6020821081036108fa57634e487b7160e01b600052602260045260246000fd5b6001600160a01b0386811682528516602082015260a060408201819052810183905260006001600160fb1b0384111561286e57600080fd5b8360051b808660c0850137808301905060c081016000815260c084830301606085015261289b81866122c4565b8481036080909501949094525050600082525060200195945050505050565b6000602082840312156128cc57600080fd5b8151610e3d8161268e565b601f821115610abf57600081815260208120601f850160051c810160208610156128fe5750805b601f850160051c820191505b81811015610dc95782815560010161290a565b67ffffffffffffffff831115612935576129356123fc565b612949836129438354612802565b836128d7565b6000601f84116001811461297d57600085156129655750838201355b600019600387901b1c1916600186901b1783556114fb565b600083815260209020601f19861690835b828110156129ae578685013582556020948501946001909201910161298e565b50868210156129cb5760001960f88860031b161c19848701351681555b505060018560011b0183555050505050565b60006001600160a01b03808716835280861660208401525083604083015260806060830152612a0f608083018461233e565b9695505050505050565b600060208284031215612a2b57600080fd5b8151610e3d8161225f565b82815260008251612a4e816020850160208701612312565b919091016020019392505050565b604080825283519082018190526000906020906060840190828701845b82811015612a9e5781516001600160a01b031684529284019290840190600101612a79565b50505083810382850152612a0f81866122c4565b60006020808385031215612ac557600080fd5b825167ffffffffffffffff80821115612add57600080fd5b818501915085601f830112612af157600080fd5b815181811115612b0357612b036123fc565b8060051b9150612b14848301612412565b8181529183018401918481019088841115612b2e57600080fd5b938501935b83851015612b4c57845182529385019390850190612b33565b98975050505050505050565b600060018201612b7857634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052601260045260246000fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a2646970667358221220ec2bd1c6bcd3828d379a4cccb828fc3d33d6b0b4c25a6589da7397be9ced88c364736f6c634300080f0033

Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.