ERC-721
Overview
Max Total Supply
4,169 BB
Holders
1,214
Market
Volume (24H)
0.042 ETH
Min Price (24H)
$71.12 @ 0.021000 ETH
Max Price (24H)
$71.12 @ 0.021000 ETH
Other Info
Token Contract
Balance
1 BBLoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
BrawlerBearz
Compiler Version
v0.8.9+commit.e5eed63a
Optimization Enabled:
Yes with 550 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol"; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import {LockRegistry} from "./abstract/LockRegistry.sol"; import {IBrawlerBearz} from "./interfaces/IBrawlerBearz.sol"; import {IBrawlerBearzFaction} from "./interfaces/IBrawlerBearzFaction.sol"; import {IBrawlerBearzRenderer} from "./interfaces/IBrawlerBearzRenderer.sol"; import {IBrawlerBearzDynamicItems} from "./interfaces/IBrawlerBearzDynamicItems.sol"; import {ERC721Psi, ERC721PsiRandomSeedReveal, ERC721PsiRandomSeedRevealBurnable} from "./ERC721PsiRandomSeedRevealBurnable.sol"; /******************************************************************************* @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|(@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@|,|@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&@@@@@@@@@@@|,*|&@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%,**%@@@@@@@@%|******%&@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&##*****|||**,(%%%%%**|%@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@***,#%%%%**#&@@@@@#**,|@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@*,(@@@@@@@@@@**,(&@@@@#**%@@@@@@||(%@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@%|,****&@((@&***&@@@@@@%||||||||#%&@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@&%#*****||||||**#%&@%%||||||||#@&%#(@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@&**,(&@@@@@%|||||*##&&&&##|||||(%@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@**,%@@@@@@@(|*|#%@@@@@@@@#||#%%@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@#||||#@@@@||*|%@@@@@@@@&|||%%&@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@#,,,,,,*|**||%|||||||###&@@@@@@@#|||#%@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@&#||*|||||%%%@%%%#|||%@@@@@@@@&(|(%&@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@&&%%(||||@@@@@@&|||||(%&((||(#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@%%(||||||||||#%#(|||||%%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@&%#######%%@@**||(#%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%##%%&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ ********************************************************************************/ /************************************************** * @title BrawlerBearz * @author @ScottMitchell18 **************************************************/ contract BrawlerBearz is IBrawlerBearz, ERC721PsiRandomSeedRevealBurnable, LockRegistry, ReentrancyGuard, AccessControl { address public constant DEAD_ADDRESS = 0x000000000000000000000000000000000000dEaD; // Roles bytes32 constant XP_MUTATOR_ROLE = keccak256("XP_MUTATOR_ROLE"); bytes32 constant OWNER_ROLE = keccak256("OWNER_ROLE"); // Equip types bytes32 constant HEAD_ITEM_TYPE = keccak256(abi.encodePacked("HEAD")); bytes32 constant WEAPON_ITEM_TYPE = keccak256(abi.encodePacked("WEAPON")); bytes32 constant BACKGROUND_ITEM_TYPE = keccak256(abi.encodePacked("BACKGROUND")); bytes32 constant ARMOR_ITEM_TYPE = keccak256(abi.encodePacked("ARMOR")); bytes32 constant FACE_ARMOR_ITEM_TYPE = keccak256(abi.encodePacked("FACE_ARMOR")); bytes32 constant EYEWEAR_ITEM_TYPE = keccak256(abi.encodePacked("EYEWEAR")); bytes32 constant MISC_ITEM_TYPE = keccak256(abi.encodePacked("MISC")); /// @notice bytes32 of Chainlink keyhash bytes32 public immutable keyHash; /// @notice value of Chainlink subscription id uint64 public immutable subscriptionId; /// @notice 4% of total minted uint256 public teamMintAmount = 128; /// @notice address of treasury (e.g, gnosis safe) address public treasury = payable(0x39bfA2b4319581bc885A2d4b9F0C90C2e1c24B87); /* * @notice Whitelist Live ~ September 16th, 2022, 10AM EST * @dev timestamp for whitelist */ uint256 public whitelistLiveAt = 1663336800; /* * @notice Public / Free Claim Live ~ September 16th, 2022, 5PM EST * @dev timestamp for public and free claim */ uint256 public liveAt = 1663362000; /// @notice amount of the total supply of the collection (n - 1) uint256 public maxSupply = 3335; // Excludes 2666 access passes /// @notice price in ether uint256 public price = 0.045 ether; /// @notice amount of transactions allowed per wallet (n - 1) uint256 public maxPerWallet = 3; /// @notice boolean for if the shop drop is enabled bool private isShopDropEnabled = true; /// @notice boolean for if its revealed bool public isRevealed = false; /// @notice bytes32 hash of the merkle root bytes32 public merkleRoot; /// @notice map from token id to custom metadata mapping(uint256 => CustomMetadata) internal metadata; // @dev An address mapping for max mint per wallet mapping(address => uint256) public addressToMinted; /// @notice Vendor contract IBrawlerBearzDynamicItems public vendorContract; /// @notice Access pass contract IERC721 public accessPassContract; /// @notice The rendering library contract IBrawlerBearzRenderer public renderer; /// @notice Faction contract IBrawlerBearzFaction public factionContract; // ======================================== // Modifiers // ======================================== modifier isTokenOwner(uint256 tokenId) { if (ownerOf(tokenId) != _msgSender()) { revert InvalidOwner(); } _; } modifier isItemTokenOwner(uint256 itemTokenId) { if (vendorContract.balanceOf(_msgSender(), itemTokenId) == 0) { revert InvalidOwner(); } _; } modifier isItemValidType(uint256 itemTokenId, string memory validTypeOf) { if ( keccak256(abi.encodePacked(validTypeOf)) != keccak256(abi.encodePacked(vendorContract.getItemType(itemTokenId))) ) { revert InvalidItemType(); } _; } modifier isItemXPMet(uint256 itemTokenId, uint256 tokenId) { if (metadata[tokenId].xp < vendorContract.getItemXPReq(itemTokenId)) { revert ItemRequiresMoreXP(); } _; } // " and \ are not valid modifier isValidString(string calldata value) { bytes memory str = bytes(value); for (uint256 i; i < str.length; i++) { bytes1 char = str[i]; if ((char == 0x22) || (char == 0x5c)) revert InvalidString(); } _; } constructor( address _vrfV2Coordinator, bytes32 keyHash_, uint64 subscriptionId_, address _accessPassContract, address _factionContract, address _renderingContract, address _vendorContract ) ERC721Psi("Brawler Bearz", "BB") ERC721PsiRandomSeedReveal(_vrfV2Coordinator, 400000, 3) { // Chainlink VRF initialization keyHash = keyHash_; subscriptionId = subscriptionId_; // Setup access control _setupRole(DEFAULT_ADMIN_ROLE, _msgSender()); _setupRole(OWNER_ROLE, _msgSender()); // NFT integration contracts accessPassContract = IERC721(_accessPassContract); factionContract = IBrawlerBearzFaction(_factionContract); // On-chain metadata rendering contract renderer = IBrawlerBearzRenderer(_renderingContract); // Shop integration contract vendorContract = IBrawlerBearzDynamicItems(_vendorContract); // Placeholder mint for collection protection _safeMint(_msgSender(), 1, ""); } // ======================================== // Dynamic metadata // ======================================== /** * @notice Sets the name of a particular token id * @dev only token owner call this function * @param tokenId The token id * @param name The name to set */ function setName(uint256 tokenId, string calldata name) public override isTokenOwner(tokenId) isValidString(name) { bytes memory n = bytes(name); if (n.length > 25) revert InvalidLength(); if (keccak256(n) == keccak256(bytes(metadata[tokenId].name))) revert InvalidValue(); metadata[tokenId].name = name; emit NameChanged(tokenId, name); } /** * @notice Sets the lore/backstory of a particular token id * @dev only token owner call this function * @param tokenId The token id * @param lore The name to set */ function setLore(uint256 tokenId, string calldata lore) public override isTokenOwner(tokenId) isValidString(lore) { bytes memory n = bytes(lore); if (keccak256(n) == keccak256(bytes(metadata[tokenId].lore))) revert InvalidValue(); metadata[tokenId].lore = lore; emit LoreChanged(tokenId, lore); } /** * @notice Sets the equipped items of a particular token id and item type * @dev only token owner call this function * @param tokenId The token id of the bear * @param typeOf The type of item to equip * @param itemTokenId The token id of the item */ function equip( uint256 tokenId, string calldata typeOf, uint256 itemTokenId ) public override isTokenOwner(tokenId) isItemTokenOwner(itemTokenId) isItemValidType(itemTokenId, typeOf) isItemXPMet(itemTokenId, tokenId) nonReentrant { bytes32 itemType = keccak256(abi.encodePacked(typeOf)); CustomMetadata storage instance = metadata[tokenId]; if (WEAPON_ITEM_TYPE == itemType) { require(instance.weapon == 0, "96"); instance.weapon = itemTokenId; } else if (HEAD_ITEM_TYPE == itemType) { require(instance.head == 0, "96"); instance.head = itemTokenId; } else if (ARMOR_ITEM_TYPE == itemType) { require(instance.armor == 0, "96"); instance.armor = itemTokenId; } else if (BACKGROUND_ITEM_TYPE == itemType) { require(instance.background == 0, "96"); instance.background = itemTokenId; } else if (FACE_ARMOR_ITEM_TYPE == itemType) { require(instance.faceArmor == 0, "96"); instance.faceArmor = itemTokenId; } else if (EYEWEAR_ITEM_TYPE == itemType) { require(instance.eyewear == 0, "96"); instance.eyewear = itemTokenId; } else if (MISC_ITEM_TYPE == itemType) { require(instance.misc == 0, "96"); instance.misc = itemTokenId; } else { revert InvalidItemType(); } // Burn item vendorContract.burnItemForOwnerAddress(itemTokenId, 1, _msgSender()); emit Equipped(tokenId, typeOf, itemTokenId); } /** * @notice Unsets the equipped items of a particular token id * @dev only token owner call this function * @param typeOf The type of item to equip * @param tokenId The token id */ function unequip(uint256 tokenId, string calldata typeOf) public override isTokenOwner(tokenId) nonReentrant { uint256 itemTokenId; bytes32 itemType = keccak256(abi.encodePacked(typeOf)); CustomMetadata storage instance = metadata[tokenId]; if (WEAPON_ITEM_TYPE == itemType) { itemTokenId = instance.weapon; instance.weapon = 0; } else if (HEAD_ITEM_TYPE == itemType) { itemTokenId = instance.head; instance.head = 0; } else if (ARMOR_ITEM_TYPE == itemType) { itemTokenId = instance.armor; instance.armor = 0; } else if (BACKGROUND_ITEM_TYPE == itemType) { itemTokenId = instance.background; instance.background = 0; } else if (FACE_ARMOR_ITEM_TYPE == itemType) { itemTokenId = instance.faceArmor; instance.faceArmor = 0; } else if (EYEWEAR_ITEM_TYPE == itemType) { itemTokenId = instance.eyewear; instance.eyewear = 0; } else if (MISC_ITEM_TYPE == itemType) { itemTokenId = instance.misc; instance.misc = 0; } else { revert InvalidItemType(); } require(itemTokenId > 0, "6969"); // Mint item vendorContract.mintItemToAddress(itemTokenId, 1, _msgSender()); emit Unequipped(tokenId, typeOf, itemTokenId); } // ======================================== // NFT display helpers // ======================================== /// @notice Reveal called by the governance to reveal the seed of the NFT function reveal() external onlyRole(OWNER_ROLE) { _reveal(); emit Revealed(totalSupply()); } /// @notice The custom metadata associated to a given tokenId function getMetadata(uint256 tokenId) external view override returns (CustomMetadata memory) { require(_exists(tokenId), "0"); return metadata[tokenId]; } /// @notice The token uri for a given tokenId function tokenURI(uint256 tokenId) public view override returns (string memory) { if (isRevealed == false) { return renderer.hiddenURI(tokenId); } require(_exists(tokenId), "0"); CustomMetadata memory md = metadata[tokenId]; md.isUnlocked = isUnlocked(tokenId); md.faction = factionContract.getFaction(ownerOf(tokenId)); return renderer.tokenURI(tokenId, seed(tokenId), md); } // ======================================== // Mint Helpers // ======================================== /** * @notice Free claim mint, requires access pass ownership * @param _tokenIds of the access pass */ function claim(uint256[] calldata _tokenIds) external nonReentrant { require(isPublicLive(), "0"); for (uint256 i = 0; i < _tokenIds.length; i++) { accessPassContract.transferFrom( _msgSender(), DEAD_ADDRESS, _tokenIds[i] ); } _safeMint(_msgSender(), _tokenIds.length, ""); } /** * @notice Whitelisted mint, requires a merkle proof * @param _amount of mints * @param _proof hashed array proof */ function whitelistMint(uint256 _amount, bytes32[] calldata _proof) external payable nonReentrant { require(isWhitelistLive(), "0"); require(totalSupply() + _amount < maxSupply, "9"); require(msg.value >= _amount * price, "1"); require(addressToMinted[_msgSender()] + _amount < maxPerWallet, "2"); bytes32 leaf = keccak256(abi.encodePacked(_msgSender())); require(MerkleProof.verify(_proof, merkleRoot, leaf), "4"); addressToMinted[_msgSender()] += _amount; _safeMint(_msgSender(), _amount, ""); // Shop drop chance game if (isShopDropEnabled) { vendorContract.shopDrop(_msgSender(), _amount); } } /** * @notice Public mint * @param _amount of mints */ function mint(uint256 _amount) external payable { require(isPublicLive(), "0"); require(totalSupply() + _amount < maxSupply, "9"); require(msg.value >= _amount * price, "1"); require(addressToMinted[_msgSender()] + _amount < maxPerWallet, "2"); addressToMinted[_msgSender()] += _amount; _safeMint(_msgSender(), _amount, ""); } /** * @notice Sets public price in wei * @dev only owner call this function * @param _price The new public price in wei */ function setPrice(uint256 _price) public onlyRole(OWNER_ROLE) { price = _price; } /** * @notice Sets the treasury recipient * @dev only owner call this function * @param _treasury The new price in wei */ function setTreasury(address _treasury) public onlyRole(OWNER_ROLE) { treasury = payable(_treasury); } /** * @notice Sets the reveal status of the metadata * @dev only owner call this function * @param _isRevealed The new boolean of the reveal */ function setIsRevealed(bool _isRevealed) public onlyRole(OWNER_ROLE) { isRevealed = _isRevealed; } /** * @notice Sets max supply for the collection * @dev only owner call this function * @param _maxSupply The new max supply value */ function setMaxSupply(uint256 _maxSupply) external onlyRole(OWNER_ROLE) { maxSupply = _maxSupply; } /** * @notice Sets the max mints per wallet * @param _maxPerWallet The max per wallet (Keep mind its +1 n) */ function setMaxPerWallet(uint256 _maxPerWallet) external onlyRole(OWNER_ROLE) { maxPerWallet = _maxPerWallet; } /** * @notice Sets the go live timestamp for whitelist * @param _whitelistLiveAt A base uri */ function setWhitelistLiveAt(uint256 _whitelistLiveAt) external onlyRole(OWNER_ROLE) { whitelistLiveAt = _whitelistLiveAt; } /** * @notice Sets the go live timestamp * @param _liveAt A base uri */ function setLiveAt(uint256 _liveAt) external onlyRole(OWNER_ROLE) { liveAt = _liveAt; } /** * @notice Sets the merkle root for the mint * @param _merkleRoot The merkle root to set */ function setMerkleRoot(bytes32 _merkleRoot) external onlyRole(OWNER_ROLE) { merkleRoot = _merkleRoot; } /// @notice Withdraw from contract function withdraw() public onlyRole(OWNER_ROLE) { (bool success, ) = treasury.call{value: address(this).balance}(""); require(success, "999"); } /// @notice Team mints ~4% of max supply - resets to 0 after team mint happens function teamMints(address _to) external onlyRole(OWNER_ROLE) { require(teamMintAmount > 0, "69"); _safeMint(_to, teamMintAmount, ""); teamMintAmount = 0; } /** * @notice Sets whether shop drop is enabled * @param _isShopDropEnabled the bool value */ function setShopDropEnabled(bool _isShopDropEnabled) external onlyRole(OWNER_ROLE) { isShopDropEnabled = _isShopDropEnabled; } // ======================================== // Lock registry // ======================================== /** * @dev Overrides the normal `transferFrom` to include lock check * @param from address * @param to address * @param tokenId of asset */ function transferFrom( address from, address to, uint256 tokenId ) public override { require(isUnlocked(tokenId), "1337"); super.transferFrom(from, to, tokenId); } /** * @dev Overrides the normal `safeTransferFrom` to include lock check * @param from address * @param to address * @param tokenId of asset */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes memory _data ) public override { require(isUnlocked(tokenId), "1337"); super.safeTransferFrom(from, to, tokenId, _data); } function lockId(uint256 tokenId) external onlyRole(XP_MUTATOR_ROLE) { require(_exists(tokenId), "0"); _lockId(tokenId); } function unlockId(uint256 tokenId) external onlyRole(XP_MUTATOR_ROLE) { require(_exists(tokenId), "0"); _unlockId(tokenId); } function freeId(uint256 tokenId, address contractAddress) external onlyRole(XP_MUTATOR_ROLE) { require(_exists(tokenId), "0"); _freeId(tokenId, contractAddress); } // ======================================== // External contract helpers // ======================================== /** * @notice Adds XP to tokenId * @param tokenId the token * @param amount of xp to add */ function addXP(uint256 tokenId, uint256 amount) external onlyRole(XP_MUTATOR_ROLE) { metadata[tokenId].xp += amount; } /** * @notice Subtracts XP from tokenId * @param tokenId the token * @param amount of xp to subtract */ function subtractXP(uint256 tokenId, uint256 amount) external onlyRole(XP_MUTATOR_ROLE) { metadata[tokenId].xp -= amount; } /** * @notice Sets the bearz rendering library contract * @dev only owner call this function * @param _renderingContractAddress The new contract address */ function setRenderingContractAddress(address _renderingContractAddress) external onlyRole(OWNER_ROLE) { renderer = IBrawlerBearzRenderer(_renderingContractAddress); } /** * @notice Sets the bearz vendor item contract * @dev only owner call this function * @param _vendorContractAddress The new contract address */ function setVendorContractAddress(address _vendorContractAddress) external onlyRole(OWNER_ROLE) { vendorContract = IBrawlerBearzDynamicItems(_vendorContractAddress); } function supportsInterface(bytes4 interfaceId) public view virtual override(ERC721Psi, AccessControl) returns (bool) { return super.supportsInterface(interfaceId); } // ======================================== // Read operations // ======================================== // @dev Check if mint is public live function isWhitelistLive() public view returns (bool) { return block.timestamp > whitelistLiveAt; } // @dev Check if mint is public live function isPublicLive() public view returns (bool) { return block.timestamp > liveAt; } // @dev Check if mint is public live function getAddressMintsRemaining(address _address) public view returns (uint256) { return maxPerWallet - addressToMinted[_address] - 1; } /* * @notice Return token ids for a given address * @param _owner address */ function walletOfOwner(address _owner) public view returns (uint256[] memory) { uint256 tokenCount = balanceOf(_owner); if (tokenCount == 0) return new uint256[](0); uint256[] memory tokensId = new uint256[](tokenCount); for (uint256 i; i < tokenCount; i++) { tokensId[i] = tokenOfOwnerByIndex(_owner, i); } return tokensId; } // ======================================== // Chainlink integrations // ======================================== function _keyHash() internal view override returns (bytes32) { return keyHash; } function _subscriptionId() internal view override returns (uint64) { return subscriptionId; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (utils/cryptography/MerkleProof.sol) pragma solidity ^0.8.0; /** * @dev These functions deal with verification of Merkle Trees proofs. * * The proofs can be generated using the JavaScript library * https://github.com/miguelmota/merkletreejs[merkletreejs]. * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled. * * See `test/utils/cryptography/MerkleProof.test.js` for some examples. * * WARNING: You should avoid using leaf values that are 64 bytes long prior to * hashing, or use a hash function other than keccak256 for hashing leaves. * This is because the concatenation of a sorted pair of internal nodes in * the merkle tree could be reinterpreted as a leaf value. */ library MerkleProof { /** * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree * defined by `root`. For this, a `proof` must be provided, containing * sibling hashes on the branch from the leaf to the root of the tree. Each * pair of leaves and each pair of pre-images are assumed to be sorted. */ function verify( bytes32[] memory proof, bytes32 root, bytes32 leaf ) internal pure returns (bool) { return processProof(proof, leaf) == root; } /** * @dev Returns the rebuilt hash obtained by traversing a Merkle tree up * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt * hash matches the root of the tree. When processing the proof, the pairs * of leafs & pre-images are assumed to be sorted. * * _Available since v4.4._ */ function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) { bytes32 computedHash = leaf; for (uint256 i = 0; i < proof.length; i++) { bytes32 proofElement = proof[i]; if (computedHash <= proofElement) { // Hash(current computed hash + current element of the proof) computedHash = _efficientHash(computedHash, proofElement); } else { // Hash(current element of the proof + current computed hash) computedHash = _efficientHash(proofElement, computedHash); } } return computedHash; } function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) { assembly { mstore(0x00, a) mstore(0x20, b) value := keccak256(0x00, 0x40) } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.6.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// 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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/access/Ownable.sol"; /* * Origin author * ,_, * (',') * {/"\} * -"-"- * Utilized by @ScottMitchell18 */ abstract contract LockRegistry is Ownable { mapping(address => bool) public approvedContract; mapping(uint256 => uint256) public lockCount; mapping(uint256 => mapping(uint256 => address)) public lockMap; mapping(uint256 => mapping(address => uint256)) public lockMapIndex; event TokenLocked( uint256 indexed tokenId, address indexed approvedContract ); event TokenUnlocked( uint256 indexed tokenId, address indexed approvedContract ); function isUnlocked(uint256 _id) public view returns (bool) { return lockCount[_id] == 0; } function updateApprovedContracts( address[] calldata _contracts, bool[] calldata _values ) external onlyOwner { require(_contracts.length == _values.length, "!length"); for (uint256 i = 0; i < _contracts.length; i++) approvedContract[_contracts[i]] = _values[i]; } function _lockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); require( lockMapIndex[_id][msg.sender] == 0, "ID already locked by caller" ); uint256 count = lockCount[_id] + 1; lockMap[_id][count] = msg.sender; lockMapIndex[_id][msg.sender] = count; lockCount[_id]++; emit TokenLocked(_id, msg.sender); } function _unlockId(uint256 _id) internal { require(approvedContract[msg.sender], "Cannot update map"); uint256 index = lockMapIndex[_id][msg.sender]; require(index != 0, "ID not locked by caller"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][msg.sender] = 0; lockCount[_id]--; emit TokenUnlocked(_id, msg.sender); } function _freeId(uint256 _id, address _contract) internal { require(!approvedContract[_contract], "Cannot update map"); uint256 index = lockMapIndex[_id][_contract]; require(index != 0, "ID not locked"); uint256 last = lockCount[_id]; if (index != last) { address lastContract = lockMap[_id][last]; lockMap[_id][index] = lastContract; lockMap[_id][last] = address(0); lockMapIndex[_id][lastContract] = index; } else lockMap[_id][index] = address(0); lockMapIndex[_id][_contract] = 0; lockCount[_id]--; emit TokenUnlocked(_id, _contract); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IBrawlerBearzCommon} from "./IBrawlerBearzCommon.sol"; import {IBrawlerBearzEvents} from "./IBrawlerBearzEvents.sol"; import {IBrawlerBearzErrors} from "./IBrawlerBearzErrors.sol"; interface IBrawlerBearz is IBrawlerBearzCommon, IBrawlerBearzEvents, IBrawlerBearzErrors { function getMetadata(uint256 tokenId) external view returns (CustomMetadata memory); function setName(uint256 tokenId, string calldata newName) external; function setLore(uint256 tokenId, string calldata newLore) external; function equip( uint256 tokenId, string calldata typeOf, uint256 itemTokenId ) external; function unequip(uint256 tokenId, string calldata typeOf) external; function whitelistMint(uint256 amount, bytes32[] calldata proof) external payable; function mint(uint256 amount) external payable; function freeId(uint256 tokenId, address contractAddress) external; function lockId(uint256 tokenId) external; function unlockId(uint256 tokenId) external; function addXP(uint256 tokenId, uint256 amount) external; function subtractXP(uint256 tokenId, uint256 amount) external; }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC1155/IERC1155.sol"; interface IBrawlerBearzFaction is IERC1155 { function getFaction(address _address) external view returns (uint256); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import {IBrawlerBearzCommon} from "./IBrawlerBearzCommon.sol"; interface IBrawlerBearzRenderer is IBrawlerBearzCommon { function hiddenURI(uint256 _tokenId) external view returns (string memory); function tokenURI( uint256 _tokenId, uint256 _seed, CustomMetadata memory _md ) external view returns (string memory); function dna( uint256 _tokenId, uint256 _seed, CustomMetadata memory _md ) external view returns (string memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "@openzeppelin/contracts-upgradeable/token/ERC1155/IERC1155Upgradeable.sol"; interface IBrawlerBearzDynamicItems is IERC1155Upgradeable { struct CustomMetadata { string typeOf; string name; uint256 xp; // Min XP required to equip string rarity; // LEGENDARY, SUPER_RARE, RARE, UNCOMMON, COMMON uint256 atk; // Correlated to Strength (5%-50%) uint256 def; // Correlated to Endurance (5%-30%), resistance to attack uint256 usageChance; // Correlated to Luck + Intelligence (20%-90%) string usageDuration; // PERSISTENT - equipable items, TEMPORARY - battles, ONE-TIME - buffs string description; } function getMetadata(uint256 tokenId) external view returns (CustomMetadata memory); function getMetadataBatch(uint256[] calldata tokenIds) external view returns (CustomMetadata[] memory); function getItemType(uint256 tokenId) external view returns (string memory); function getItemName(uint256 tokenId) external view returns (string memory); function getItemXPReq(uint256 tokenId) external view returns (uint256); function setItemMetadata( uint256 tokenId, string calldata typeOf, string calldata name, uint256 xp ) external; function setItemMetadataStruct( uint256 tokenId, CustomMetadata memory metadata ) external; function shopDrop(address _toAddress, uint256 _amount) external; function dropItems(address _toAddress, uint256[] calldata itemIds) external; function burnItemForOwnerAddress( uint256 _typeId, uint256 _quantity, address _materialOwnerAddress ) external; function mintItemToAddress( uint256 _typeId, uint256 _quantity, address _toAddress ) external; function mintBatchItemsToAddress( uint256[] memory _typeIds, uint256[] memory _quantities, address _toAddress ) external; function bulkSafeTransfer( uint256 _typeId, uint256 _quantityPerRecipient, address[] calldata recipients ) external; }
// SPDX-License-Identifier: MIT /** ______ _____ _____ ______ ___ __ _ _ _ | ____| __ \ / ____|____ |__ \/_ | || || | | |__ | |__) | | / / ) || | \| |/ | | __| | _ /| | / / / / | |\_ _/ | |____| | \ \| |____ / / / /_ | | | | |______|_| \_\\_____|/_/ |____||_| |_| */ pragma solidity ^0.8.0; import "./BitMaps.sol"; import "./ERC721PsiRandomSeedReveal.sol"; abstract contract ERC721PsiRandomSeedRevealBurnable is ERC721PsiRandomSeedReveal { using BitMaps for BitMaps.BitMap; BitMaps.BitMap private _burnedToken; /** * @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 from = ownerOf(tokenId); _beforeTokenTransfers(from, address(0), tokenId, 1); _burnedToken.set(tokenId); emit Transfer(from, address(0), tokenId); _afterTokenTransfers(from, address(0), tokenId, 1); } /** * @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 override returns (bool) { if (_burnedToken.get(tokenId)) { return false; } return super._exists(tokenId); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _minted - _burned(); } /** * @dev Returns number of token burned. */ function _burned() internal view returns (uint256 burned) { uint256 totalBucket = (_minted >> 8) + 1; for (uint256 i = 0; i < totalBucket; i++) { uint256 bucket = _burnedToken.getBucket(i); burned += _popcount(bucket); } } /** * @dev Returns number of set bits. */ function _popcount(uint256 x) private pure returns (uint256 count) { unchecked { for (count = 0; x != 0; count++) x &= x - 1; } } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// 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; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/Strings.sol) 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 // OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol) 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 // 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); }
// 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); } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IBrawlerBearzCommon { struct CustomMetadata { string name; string lore; uint256 background; uint256 head; uint256 weapon; uint256 armor; uint256 faceArmor; uint256 eyewear; uint256 misc; uint256 xp; bool isUnlocked; uint256 faction; } struct Traits { uint256 strength; uint256 endurance; uint256 intelligence; uint256 luck; uint256 xp; uint256 level; string skin; string head; string eyes; string outfit; string mouth; string background; string weapon; string armor; string eyewear; string faceArmor; string misc; string locked; string faction; } struct Bear { string name; string description; string dna; Traits traits; CustomMetadata dynamic; } }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IBrawlerBearzEvents { event Revealed(uint256 currentTokenId); event NameChanged(uint256 indexed id, string name); event LoreChanged(uint256 indexed id, string lore); event Equipped(uint256 indexed id, string typeOf, uint256 itemTokenId); event Unequipped(uint256 indexed id, string typeOf, uint256 itemTokenId); event Staked(uint256 indexed id); event UnStaked(uint256 indexed id, uint256 amount); event ClaimedTokens(uint256 indexed id, uint256 amount); }
//SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IBrawlerBearzErrors { error InvalidRecipient(); error InvalidTokenIds(); error InvalidOwner(); error InvalidItemType(); error InvalidString(); error InvalidLength(); error InvalidValue(); error ItemRequiresMoreXP(); }
// 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; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol) pragma solidity ^0.8.0; import "../../utils/introspection/IERC165Upgradeable.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 IERC1155Upgradeable is IERC165Upgradeable { /** * @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; }
// 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 IERC165Upgradeable { /** * @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 "./BitScan.sol"; /** * @dev This Library is a modified version of Openzeppelin's BitMaps library. * Functions of finding the index of the closest set bit from a given index are added. * The indexing of each bucket is modifed to count from the MSB to the LSB instead of from the LSB to the MSB. * The modification of indexing makes finding the closest previous set bit more efficient in gas usage. */ /** * @dev Library for managing uint256 to bool mapping in a compact and efficient way, providing the keys are sequential. * Largelly inspired by Uniswap's https://github.com/Uniswap/merkle-distributor/blob/master/contracts/MerkleDistributor.sol[merkle-distributor]. */ library BitMaps { using BitScan for uint256; uint256 private constant MASK_INDEX_ZERO = (1 << 255); struct BitMap { mapping(uint256 => uint256) _data; } /** * @dev Returns whether the bit at `index` is set. */ function get(BitMap storage bitmap, uint256 index) internal view returns (bool) { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); return bitmap._data[bucket] & mask != 0; } /** * @dev Sets the bit at `index` to the boolean `value`. */ function setTo( BitMap storage bitmap, uint256 index, bool value ) internal { if (value) { set(bitmap, index); } else { unset(bitmap, index); } } /** * @dev Sets the bit at `index`. */ function set(BitMap storage bitmap, uint256 index) internal { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); bitmap._data[bucket] |= mask; } /** * @dev Unsets the bit at `index`. */ function unset(BitMap storage bitmap, uint256 index) internal { uint256 bucket = index >> 8; uint256 mask = MASK_INDEX_ZERO >> (index & 0xff); bitmap._data[bucket] &= ~mask; } /** * @dev Find the closest index of the set bit before `index`. */ function scanForward(BitMap storage bitmap, uint256 index) internal view returns (uint256) { uint256 bucket = index >> 8; uint256 bucketIndex = (index & 0xff); uint256 offset = 0xff ^ bucketIndex; uint256 bb = bitmap._data[bucket]; bb = bb >> offset; if (bb > 0) { unchecked { return (bucket << 8) | (bucketIndex - bb.bitScanForward256()); } } else { require(bucket > 0, "!exists"); unchecked { bucket--; bucketIndex = 255; offset = 0; } while (true) { bb = bitmap._data[bucket]; if (bb > 0) { unchecked { return (bucket << 8) | (bucketIndex - bb.bitScanForward256()); } } else { require(bucket > 0, "!existS"); unchecked { bucket--; } } } } } function getBucket(BitMap storage bitmap, uint256 bucket) internal view returns (uint256) { return bitmap._data[bucket]; } }
// SPDX-License-Identifier: MIT /** ______ _____ _____ ______ ___ __ _ _ _ | ____| __ \ / ____|____ |__ \/_ | || || | | |__ | |__) | | / / ) || | \| |/ | | __| | _ /| | / / / / | |\_ _/ | |____| | \ \| |____ / / / /_ | | | | |______|_| \_\\_____|/_/ |____||_| |_| */ pragma solidity ^0.8.0; import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol"; import "./interfaces/IERC721RandomSeed.sol"; import "./BitMaps.sol"; import "./ERC721PsiBatchMetaData.sol"; abstract contract ERC721PsiRandomSeedReveal is IERC721RandomSeed, ERC721PsiBatchMetaData, VRFConsumerBaseV2 { // Chainklink VRF V2 VRFCoordinatorV2Interface immutable COORDINATOR; uint32 immutable callbackGasLimit; uint16 immutable requestConfirmations; uint16 constant numWords = 1; // requestId => genId mapping(uint256 => uint256) private requestIdToGenId; // genId => seed mapping(uint256 => uint256) private genSeed; // batchHeadTokenId => genId mapping(uint256 => uint256) private _batchHeadtokenGen; // current genId for minting uint256 private currentGen = 1; event RandomnessRequest(uint256 requestId); constructor( address coordinator, uint32 _callbackGasLimit, uint16 _requestConfirmations ) VRFConsumerBaseV2(coordinator) { COORDINATOR = VRFCoordinatorV2Interface(coordinator); callbackGasLimit = _callbackGasLimit; requestConfirmations = _requestConfirmations; } /** * Callback function used by VRF Coordinator */ function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { uint256 randomness = randomWords[0]; uint256 genId = requestIdToGenId[requestId]; delete requestIdToGenId[genId]; genSeed[genId] = randomness; _processRandomnessFulfillment(requestId, genId, randomness); } function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual override { uint256 tokenIdHead = _minted; _batchHeadtokenGen[tokenIdHead] = currentGen; super._safeMint(to, quantity, _data); } /** @dev Query the generation of `tokenId`. */ function _tokenGen(uint256 tokenId) internal view returns (uint256) { require(_exists(tokenId), "!exists"); return _batchHeadtokenGen[_getMetaDataBatchHead(tokenId)]; } /** @dev Request the randomess for the tokens of the current generation. */ function _reveal() internal virtual { uint256 requestId = COORDINATOR.requestRandomWords( _keyHash(), _subscriptionId(), requestConfirmations, callbackGasLimit, numWords ); emit RandomnessRequest(requestId); requestIdToGenId[requestId] = currentGen; _processRandomnessRequest(requestId, currentGen); currentGen++; } /** @dev Return the random seed of `tokenId`. Revert when the randomness hasn't been fulfilled. */ function seed(uint256 tokenId) public view virtual override returns (uint256) { require(_exists(tokenId), "!exists"); unchecked { uint256 _genSeed = genSeed[_tokenGen(tokenId)]; require(_genSeed != 0, "!fullfilled"); return uint256(keccak256(abi.encode(_genSeed, tokenId))); } } /** @dev Override the function to provide the corrosponding keyHash for the Chainlink VRF V2. see also: https://docs.chain.link/docs/vrf-contracts/ */ function _keyHash() internal virtual returns (bytes32); /** @dev Override the function to provide the corrosponding subscription id for the Chainlink VRF V2. see also: https://docs.chain.link/docs/get-a-random-number/#create-and-fund-a-subscription */ function _subscriptionId() internal virtual returns (uint64); function _processRandomnessRequest(uint256 requestId, uint256 genId) internal {} function _processRandomnessFulfillment( uint256 requestId, uint256 genId, uint256 randomness ) internal {} }
// SPDX-License-Identifier: MIT /** ______ _____ _____ ______ ___ __ _ _ _ | ____| __ \ / ____|____ |__ \/_ | || || | | |__ | |__) | | / / ) || | \| |/ | | __| | _ /| | / / / / | |\_ _/ | |____| | \ \| |____ / / / /_ | | | | |______|_| \_\\_____|/_/ |____||_| |_| */ pragma solidity ^0.8.0; library BitScan { uint256 private constant DEBRUIJN_256 = 0x818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff; bytes private constant LOOKUP_TABLE_256 = hex"0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8"; function isolateLSB256(uint256 bb) internal pure returns (uint256) { require(bb > 0); unchecked { return bb & (0 - bb); } } function isolateMSB256(uint256 bb) internal pure returns (uint256) { require(bb > 0); unchecked { bb |= bb >> 256; bb |= bb >> 128; bb |= bb >> 64; bb |= bb >> 32; bb |= bb >> 16; bb |= bb >> 8; bb |= bb >> 4; bb |= bb >> 2; bb |= bb >> 1; return (bb >> 1) + 1; } } function bitScanForward256(uint256 bb) internal pure returns (uint8) { unchecked { return uint8( LOOKUP_TABLE_256[(isolateLSB256(bb) * DEBRUIJN_256) >> 248] ); } } function bitScanReverse256(uint256 bb) internal pure returns (uint8) { unchecked { return 255 - uint8( LOOKUP_TABLE_256[ ((isolateMSB256(bb) * DEBRUIJN_256) >> 248) ] ); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface VRFCoordinatorV2Interface { /** * @notice Get configuration relevant for making requests * @return minimumRequestConfirmations global min for request confirmations * @return maxGasLimit global max for request gas limit * @return s_provingKeyHashes list of registered key hashes */ function getRequestConfig() external view returns ( uint16, uint32, bytes32[] memory ); /** * @notice Request a set of random words. * @param keyHash - Corresponds to a particular oracle job which uses * that key for generating the VRF proof. Different keyHash's have different gas price * ceilings, so you can select a specific one to bound your maximum per request cost. * @param subId - The ID of the VRF subscription. Must be funded * with the minimum subscription balance required for the selected keyHash. * @param minimumRequestConfirmations - How many blocks you'd like the * oracle to wait before responding to the request. See SECURITY CONSIDERATIONS * for why you may want to request more. The acceptable range is * [minimumRequestBlockConfirmations, 200]. * @param callbackGasLimit - How much gas you'd like to receive in your * fulfillRandomWords callback. Note that gasleft() inside fulfillRandomWords * may be slightly less than this amount because of gas used calling the function * (argument decoding etc.), so you may need to request slightly more than you expect * to have inside fulfillRandomWords. The acceptable range is * [0, maxGasLimit] * @param numWords - The number of uint256 random values you'd like to receive * in your fulfillRandomWords callback. Note these numbers are expanded in a * secure way by the VRFCoordinator from a single random value supplied by the oracle. * @return requestId - A unique identifier of the request. Can be used to match * a request to a response in fulfillRandomWords. */ function requestRandomWords( bytes32 keyHash, uint64 subId, uint16 minimumRequestConfirmations, uint32 callbackGasLimit, uint32 numWords ) external returns (uint256 requestId); /** * @notice Create a VRF subscription. * @return subId - A unique subscription id. * @dev You can manage the consumer set dynamically with addConsumer/removeConsumer. * @dev Note to fund the subscription, use transferAndCall. For example * @dev LINKTOKEN.transferAndCall( * @dev address(COORDINATOR), * @dev amount, * @dev abi.encode(subId)); */ function createSubscription() external returns (uint64 subId); /** * @notice Get a VRF subscription. * @param subId - ID of the subscription * @return balance - LINK balance of the subscription in juels. * @return reqCount - number of requests for this subscription, determines fee tier. * @return owner - owner of the subscription. * @return consumers - list of consumer address which are able to use this subscription. */ function getSubscription(uint64 subId) external view returns ( uint96 balance, uint64 reqCount, address owner, address[] memory consumers ); /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @param newOwner - proposed new owner of the subscription */ function requestSubscriptionOwnerTransfer(uint64 subId, address newOwner) external; /** * @notice Request subscription owner transfer. * @param subId - ID of the subscription * @dev will revert if original owner of subId has * not requested that msg.sender become the new owner. */ function acceptSubscriptionOwnerTransfer(uint64 subId) external; /** * @notice Add a consumer to a VRF subscription. * @param subId - ID of the subscription * @param consumer - New consumer which can use the subscription */ function addConsumer(uint64 subId, address consumer) external; /** * @notice Remove a consumer from a VRF subscription. * @param subId - ID of the subscription * @param consumer - Consumer to remove from the subscription */ function removeConsumer(uint64 subId, address consumer) external; /** * @notice Cancel a subscription * @param subId - ID of the subscription * @param to - Where to send the remaining LINK to */ function cancelSubscription(uint64 subId, address to) external; }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; /** **************************************************************************** * @notice Interface for contracts using VRF randomness * ***************************************************************************** * @dev PURPOSE * * @dev Reggie the Random Oracle (not his real job) wants to provide randomness * @dev to Vera the verifier in such a way that Vera can be sure he's not * @dev making his output up to suit himself. Reggie provides Vera a public key * @dev to which he knows the secret key. Each time Vera provides a seed to * @dev Reggie, he gives back a value which is computed completely * @dev deterministically from the seed and the secret key. * * @dev Reggie provides a proof by which Vera can verify that the output was * @dev correctly computed once Reggie tells it to her, but without that proof, * @dev the output is indistinguishable to her from a uniform random sample * @dev from the output space. * * @dev The purpose of this contract is to make it easy for unrelated contracts * @dev to talk to Vera the verifier about the work Reggie is doing, to provide * @dev simple access to a verifiable source of randomness. It ensures 2 things: * @dev 1. The fulfillment came from the VRFCoordinator * @dev 2. The consumer contract implements fulfillRandomWords. * ***************************************************************************** * @dev USAGE * * @dev Calling contracts must inherit from VRFConsumerBase, and can * @dev initialize VRFConsumerBase's attributes in their constructor as * @dev shown: * * @dev contract VRFConsumer { * @dev constructor(<other arguments>, address _vrfCoordinator, address _link) * @dev VRFConsumerBase(_vrfCoordinator) public { * @dev <initialization with other arguments goes here> * @dev } * @dev } * * @dev The oracle will have given you an ID for the VRF keypair they have * @dev committed to (let's call it keyHash). Create subscription, fund it * @dev and your consumer contract as a consumer of it (see VRFCoordinatorInterface * @dev subscription management functions). * @dev Call requestRandomWords(keyHash, subId, minimumRequestConfirmations, * @dev callbackGasLimit, numWords), * @dev see (VRFCoordinatorInterface for a description of the arguments). * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomWords method. * * @dev The randomness argument to fulfillRandomWords is a set of random words * @dev generated from your requestId and the blockHash of the request. * * @dev If your contract could have concurrent requests open, you can use the * @dev requestId returned from requestRandomWords to track which response is associated * @dev with which randomness request. * @dev See "SECURITY CONSIDERATIONS" for principles to keep in mind, * @dev if your contract could have multiple requests in flight simultaneously. * * @dev Colliding `requestId`s are cryptographically impossible as long as seeds * @dev differ. * * ***************************************************************************** * @dev SECURITY CONSIDERATIONS * * @dev A method with the ability to call your fulfillRandomness method directly * @dev could spoof a VRF response with any random value, so it's critical that * @dev it cannot be directly called by anything other than this base contract * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method). * * @dev For your users to trust that your contract's random behavior is free * @dev from malicious interference, it's best if you can write it so that all * @dev behaviors implied by a VRF response are executed *during* your * @dev fulfillRandomness method. If your contract must store the response (or * @dev anything derived from it) and use it later, you must ensure that any * @dev user-significant behavior which depends on that stored value cannot be * @dev manipulated by a subsequent VRF request. * * @dev Similarly, both miners and the VRF oracle itself have some influence * @dev over the order in which VRF responses appear on the blockchain, so if * @dev your contract could have multiple VRF requests in flight simultaneously, * @dev you must ensure that the order in which the VRF responses arrive cannot * @dev be used to manipulate your contract's user-significant behavior. * * @dev Since the block hash of the block which contains the requestRandomness * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful * @dev miner could, in principle, fork the blockchain to evict the block * @dev containing the request, forcing the request to be included in a * @dev different block with a different hash, and therefore a different input * @dev to the VRF. However, such an attack would incur a substantial economic * @dev cost. This cost scales with the number of blocks the VRF oracle waits * @dev until it calls responds to a request. It is for this reason that * @dev that you can signal to an oracle you'd like them to wait longer before * @dev responding to the request (however this is not enforced in the contract * @dev and so remains effective only in the case of unmodified oracle software). */ abstract contract VRFConsumerBaseV2 { error OnlyCoordinatorCanFulfill(address have, address want); address private immutable vrfCoordinator; /** * @param _vrfCoordinator address of VRFCoordinator contract */ constructor(address _vrfCoordinator) { vrfCoordinator = _vrfCoordinator; } /** * @notice fulfillRandomness handles the VRF response. Your contract must * @notice implement it. See "SECURITY CONSIDERATIONS" above for important * @notice principles to keep in mind when implementing your fulfillRandomness * @notice method. * * @dev VRFConsumerBaseV2 expects its subcontracts to have a method with this * @dev signature, and will call it once it has verified the proof * @dev associated with the randomness. (It is triggered via a call to * @dev rawFulfillRandomness, below.) * * @param requestId The Id initially returned by requestRandomness * @param randomWords the VRF output expanded to the requested number of words */ function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal virtual; // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomWords(uint256 requestId, uint256[] memory randomWords) external { if (msg.sender != vrfCoordinator) { revert OnlyCoordinatorCanFulfill(msg.sender, vrfCoordinator); } fulfillRandomWords(requestId, randomWords); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface IERC721RandomSeed { function seed(uint256 tokenId) external view returns (uint256); }
// SPDX-License-Identifier: MIT /** ______ _____ _____ ______ ___ __ _ _ _ | ____| __ \ / ____|____ |__ \/_ | || || | | |__ | |__) | | / / ) || | \| |/ | | __| | _ /| | / / / / | |\_ _/ | |____| | \ \| |____ / / / /_ | | | | |______|_| \_\\_____|/_/ |____||_| |_| */ pragma solidity ^0.8.0; import "./ERC721Psi.sol"; import "./BitMaps.sol"; abstract contract ERC721PsiBatchMetaData is ERC721Psi { using BitMaps for BitMaps.BitMap; BitMaps.BitMap private _metaDataBatchHead; function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual override { uint256 tokenIdBatchHead = _minted; _metaDataBatchHead.set(tokenIdBatchHead); super._safeMint(to, quantity, _data); } /** * @dev Return the batch head tokenId where the on-chain metadata is stored during minting. * * The returned tokenId will remain the same after the token transfer. */ function _getMetaDataBatchHead(uint256 tokenId) internal view returns (uint256 tokenIdMetaDataBatchHead) { tokenIdMetaDataBatchHead = _metaDataBatchHead.scanForward(tokenId); } }
// SPDX-License-Identifier: MIT /** ______ _____ _____ ______ ___ __ _ _ _ | ____| __ \ / ____|____ |__ \/_ | || || | | |__ | |__) | | / / ) || | \| |/ | | __| | _ /| | / / / / | |\_ _/ | |____| | \ \| |____ / / / /_ | | | | |______|_| \_\\_____|/_/ |____||_| |_| */ pragma solidity ^0.8.0; import "@openzeppelin/contracts/token/ERC721/IERC721.sol"; import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol"; import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol"; import "@openzeppelin/contracts/utils/Context.sol"; import "@openzeppelin/contracts/utils/Strings.sol"; import "@openzeppelin/contracts/utils/introspection/ERC165.sol"; import "./BitMaps.sol"; import "./Address.sol"; contract ERC721Psi is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using Address for address; using Strings for uint256; using BitMaps for BitMaps.BitMap; BitMaps.BitMap private _batchHead; string private _name; string private _symbol; // Mapping from token ID to owner address mapping(uint256 => address) internal _owners; uint256 internal _minted; mapping(uint256 => address) private _tokenApprovals; 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 || interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId); } /** * @dev See {IERC721-balanceOf}. */ function balanceOf(address owner) public view virtual override returns (uint256) { require(owner != address(0), "zero address"); uint256 count; for (uint256 i; i < _minted; ++i) { if (_exists(i)) { if (owner == ownerOf(i)) { ++count; } } } return count; } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view virtual override returns (address) { (address owner, uint256 tokenIdBatchHead) = _ownerAndBatchHeadOf( tokenId ); return owner; } function _ownerAndBatchHeadOf(uint256 tokenId) internal view returns (address owner, uint256 tokenIdBatchHead) { require(_exists(tokenId), "!exists"); tokenIdBatchHead = _getBatchHead(tokenId); owner = _owners[tokenIdBatchHead]; } /** * @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), "!exists"); 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 = ownerOf(tokenId); require(to != owner, "!approval"); require( _msgSender() == owner || isApprovedForAll(owner, _msgSender()), "!approved" ); _approve(to, tokenId); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view virtual override returns (address) { require(_exists(tokenId), "!exists"); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public virtual override { require(operator != _msgSender(), "!approve"); _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), "!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), "!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), "!ERC721Receiver" ); } /** * @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`). */ function _exists(uint256 tokenId) internal view virtual returns (bool) { return tokenId < _minted; } /** * @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), "!exist"); address owner = ownerOf(tokenId); return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender)); } /** * @dev Safely mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called for each safe transfer. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _safeMint(address to, uint256 quantity) internal virtual { _safeMint(to, quantity, ""); } function _safeMint( address to, uint256 quantity, bytes memory _data ) internal virtual { uint256 tokenIdBatchHead = _minted; require(quantity > 0, "zero"); require(to != address(0), "!zeroaddress"); _beforeTokenTransfers(address(0), to, tokenIdBatchHead, quantity); for (uint256 i = 0; i < quantity; i++) { uint256 tokenId = tokenIdBatchHead + i; emit Transfer(address(0), to, tokenId); require( _checkOnERC721Received(address(0), to, tokenId, _data), "!ERC721Receiver" ); } _owners[tokenIdBatchHead] = to; _batchHead.set(tokenIdBatchHead); _minted += quantity; _afterTokenTransfers(address(0), to, tokenIdBatchHead, quantity); } /** * @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 { (address owner, uint256 tokenIdBatchHead) = _ownerAndBatchHeadOf( tokenId ); require(owner == from, "notown"); require(to != address(0), "zeroaddress"); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner _approve(address(0), tokenId); uint256 nextTokenId = tokenId + 1; if (!_batchHead.get(nextTokenId) && nextTokenId < _minted) { _owners[nextTokenId] = from; _batchHead.set(nextTokenId); } _owners[tokenId] = to; if (tokenId != tokenIdBatchHead) { _batchHead.set(tokenId); } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve(address to, uint256 tokenId) internal virtual { _tokenApprovals[tokenId] = to; emit Approval(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("!ERC721Receiver"); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } function _getBatchHead(uint256 tokenId) internal view returns (uint256 tokenIdBatchHead) { tokenIdBatchHead = _batchHead.scanForward(tokenId); } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view virtual override returns (uint256) { return _minted; } /** * @dev See {IERC721Enumerable-tokenByIndex}. */ function tokenByIndex(uint256 index) public view virtual override returns (uint256) { require(index < totalSupply(), "oob"); uint256 count; for (uint256 i; i < _minted; i++) { if (_exists(i)) { if (count == index) return i; else count++; } } } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256 tokenId) { uint256 count; for (uint256 i; i < _minted; i++) { if (_exists(i) && owner == ownerOf(i)) { if (count == index) return i; else count++; } } revert("oob"); } /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * 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`. */ function _beforeTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} /** * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes * minting. * * startTokenId - the first token id to be transferred * quantity - the amount to be transferred * * Calling conditions: * * - when `from` and `to` are both non-zero. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} }
// 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); }
// 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); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol) 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); /** * @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); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.9; library Address { function isContract(address account) internal view returns (bool) { uint size; assembly { size := extcodesize(account) } return size > 0; } }
{ "optimizer": { "enabled": true, "runs": 550, "details": { "yul": false } }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "metadata": { "useLiteralContent": true }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vrfV2Coordinator","type":"address"},{"internalType":"bytes32","name":"keyHash_","type":"bytes32"},{"internalType":"uint64","name":"subscriptionId_","type":"uint64"},{"internalType":"address","name":"_accessPassContract","type":"address"},{"internalType":"address","name":"_factionContract","type":"address"},{"internalType":"address","name":"_renderingContract","type":"address"},{"internalType":"address","name":"_vendorContract","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"InvalidItemType","type":"error"},{"inputs":[],"name":"InvalidLength","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidString","type":"error"},{"inputs":[],"name":"InvalidTokenIds","type":"error"},{"inputs":[],"name":"InvalidValue","type":"error"},{"inputs":[],"name":"ItemRequiresMoreXP","type":"error"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","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":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ClaimedTokens","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"typeOf","type":"string"},{"indexed":false,"internalType":"uint256","name":"itemTokenId","type":"uint256"}],"name":"Equipped","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"lore","type":"string"}],"name":"LoreChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"name","type":"string"}],"name":"NameChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"requestId","type":"uint256"}],"name":"RandomnessRequest","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"currentTokenId","type":"uint256"}],"name":"Revealed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"Staked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenLocked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"approvedContract","type":"address"}],"name":"TokenUnlocked","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":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"UnStaked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"string","name":"typeOf","type":"string"},{"indexed":false,"internalType":"uint256","name":"itemTokenId","type":"uint256"}],"name":"Unequipped","type":"event"},{"inputs":[],"name":"DEAD_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"accessPassContract","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"addXP","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressToMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"","type":"address"}],"name":"approvedContract","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"_tokenIds","type":"uint256[]"}],"name":"claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"typeOf","type":"string"},{"internalType":"uint256","name":"itemTokenId","type":"uint256"}],"name":"equip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"factionContract","outputs":[{"internalType":"contract IBrawlerBearzFaction","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"contractAddress","type":"address"}],"name":"freeId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"getAddressMintsRemaining","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getMetadata","outputs":[{"components":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"lore","type":"string"},{"internalType":"uint256","name":"background","type":"uint256"},{"internalType":"uint256","name":"head","type":"uint256"},{"internalType":"uint256","name":"weapon","type":"uint256"},{"internalType":"uint256","name":"armor","type":"uint256"},{"internalType":"uint256","name":"faceArmor","type":"uint256"},{"internalType":"uint256","name":"eyewear","type":"uint256"},{"internalType":"uint256","name":"misc","type":"uint256"},{"internalType":"uint256","name":"xp","type":"uint256"},{"internalType":"bool","name":"isUnlocked","type":"bool"},{"internalType":"uint256","name":"faction","type":"uint256"}],"internalType":"struct IBrawlerBearzCommon.CustomMetadata","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":[],"name":"isPublicLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRevealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"isUnlocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isWhitelistLive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"keyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"liveAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"lockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"lockMap","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"address","name":"","type":"address"}],"name":"lockMapIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPerWallet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"requestId","type":"uint256"},{"internalType":"uint256[]","name":"randomWords","type":"uint256[]"}],"name":"rawFulfillRandomWords","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"contract IBrawlerBearzRenderer","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","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":"uint256","name":"tokenId","type":"uint256"}],"name":"seed","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":"bool","name":"_isRevealed","type":"bool"}],"name":"setIsRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_liveAt","type":"uint256"}],"name":"setLiveAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"lore","type":"string"}],"name":"setLore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxPerWallet","type":"uint256"}],"name":"setMaxPerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_merkleRoot","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"name","type":"string"}],"name":"setName","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_renderingContractAddress","type":"address"}],"name":"setRenderingContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isShopDropEnabled","type":"bool"}],"name":"setShopDropEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_vendorContractAddress","type":"address"}],"name":"setVendorContractAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_whitelistLiveAt","type":"uint256"}],"name":"setWhitelistLiveAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"subscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"subtractXP","outputs":[],"stateMutability":"nonpayable","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":[],"name":"teamMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"teamMints","outputs":[],"stateMutability":"nonpayable","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":"tokenId","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":"treasury","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"typeOf","type":"string"}],"name":"unequip","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"unlockId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_contracts","type":"address[]"},{"internalType":"bool[]","name":"_values","type":"bool[]"}],"name":"updateApprovedContracts","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vendorContract","outputs":[{"internalType":"contract IBrawlerBearzDynamicItems","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"whitelistLiveAt","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"},{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
6101406040526001600b8190556080601455601580546001600160a01b0319167339bfa2b4319581bc885a2d4b9f0c90c2e1c24b871790556363248160601655636324e3d0601755610d07601855669fdf42f6e480006019556003601a55601b805461ffff191690911790553480156200007857600080fd5b5060405162006a0a38038062006a0a8339810160408190526200009b9162000763565b8662061a806003826040518060400160405280600d81526020016c213930bbb632b9102132b0b93d60991b81525060405180604001604052806002815260200161212160f11b8152508160019080519060200190620000fc92919062000653565b5080516200011290600290602084019062000653565b5050506001600160a01b039081166080529290921660a05263ffffffff1660c05261ffff1660e052620001453362000207565b60016012556101008690526001600160401b038516610120526200016b60003362000259565b620001977fb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e3362000259565b602080546001600160a01b038681166001600160a01b03199283161783556022805487831690841617905560218054868316908416179055601f80549185169190921617905560408051918201905260008152620001fa90339060019062000269565b5050505050505062000a52565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b620002658282620002a8565b5050565b60006004549050600b54600a600083815260200190815260200160002081905550620002a28484846200033260201b620033a51760201c565b50505050565b620002b4828262000366565b620002655760008281526013602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620002ee3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6004546200034e60078262000393602090811b620033d517901c565b620002a2848484620003bf60201b620034011760201c565b60008281526013602090815260408083206001600160a01b038516845290915290205460ff165b92915050565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b60045482620003eb5760405162461bcd60e51b8152600401620003e29062000830565b60405180910390fd5b6001600160a01b038416620004145760405162461bcd60e51b8152600401620003e29062000866565b60005b83811015620004ad5760006200042e82846200088e565b60405190915081906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46200047860008783876200051d565b620004975760405162461bcd60e51b8152600401620003e290620008d0565b5080620004a481620008e2565b91505062000417565b506000818152600360209081526040822080546001600160a01b0319166001600160a01b038816179055620004ee9190839062000393811b620033d517901c565b82600460008282546200050291906200088e565b90915550620002a2905060008583866001600160e01b038516565b60006200053e846001600160a01b03166200064d60201b6200353f1760201c565b156200064157604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290620005789033908990889088906004016200097c565b602060405180830381600087803b1580156200059357600080fd5b505af1925050508015620005c6575060408051601f3d908101601f19168201909252620005c391810190620009e6565b60015b62000626573d808015620005f7576040519150601f19603f3d011682016040523d82523d6000602084013e620005fc565b606091505b5080516200061e5760405162461bcd60e51b8152600401620003e290620008d0565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905062000645565b5060015b949350505050565b3b151590565b828054620006619062000a21565b90600052602060002090601f016020900481019282620006855760008555620006d0565b82601f10620006a057805160ff1916838001178555620006d0565b82800160010185558215620006d0579182015b82811115620006d0578251825591602001919060010190620006b3565b50620006de929150620006e2565b5090565b5b80821115620006de5760008155600101620006e3565b60006001600160a01b0382166200038d565b6200071681620006f9565b81146200072257600080fd5b50565b80516200038d816200070b565b8062000716565b80516200038d8162000732565b6001600160401b03811662000716565b80516200038d8162000746565b600080600080600080600060e0888a031215620007835762000783600080fd5b6000620007918a8a62000725565b9750506020620007a48a828b0162000739565b9650506040620007b78a828b0162000756565b9550506060620007ca8a828b0162000725565b9450506080620007dd8a828b0162000725565b93505060a0620007f08a828b0162000725565b92505060c0620008038a828b0162000725565b91505092959891949750929550565b60048152600060208201637a65726f60e01b815291505b5060200190565b602080825281016200038d8162000812565b600c81526000602082016b217a65726f6164647265737360a01b8152915062000829565b602080825281016200038d8162000842565b634e487b7160e01b600052601160045260246000fd5b60008219821115620008a457620008a462000878565b500190565b600f81526000602082016e10a2a9219b9918a932b1b2b4bb32b960891b8152915062000829565b602080825281016200038d81620008a9565b6000600019821415620008f957620008f962000878565b5060010190565b6200090b81620006f9565b82525050565b806200090b565b60005b83811015620009355781810151838201526020016200091b565b83811115620002a25750506000910152565b600062000952825190565b8084526020840193506200096b81856020860162000918565b601f01601f19169290920192915050565b608081016200098c828762000900565b6200099b602083018662000900565b620009aa604083018562000911565b8181036060830152620009be818462000947565b9695505050505050565b6001600160e01b0319811662000716565b80516200038d81620009c8565b600060208284031215620009fd57620009fd600080fd5b6000620006458484620009d9565b634e487b7160e01b600052602260045260246000fd5b60028104600182168062000a3657607f821691505b6020821081141562000a4c5762000a4c62000a0b565b50919050565b60805160a05160c05160e0516101005161012051615f5362000ab7600039600081816105be0152613da001526000818161096c0152613d7e01526000613dc201526000613de401526000613d4901526000818161112901526111510152615f536000f3fe60806040526004361061048e5760003560e01c80636f8b44b011610265578063a574cea411610154578063d2cab056116100d1578063e268e4d311610095578063f0f442601161006f578063f0f4426014610ef2578063f2fde38b14610f12578063fe55932a14610f3257600080fd5b8063e268e4d314610e69578063e985e9c514610e89578063ea07e68a14610ed257600080fd5b8063d2cab05614610de0578063d50efd7014610df3578063d547741f14610e13578063d5abeb0114610e33578063d6257bb814610e4957600080fd5b8063b7b2040411610118578063b7b2040414610d4a578063b88d4fde14610d60578063c87b56dd14610d80578063ca2eb5ae14610da0578063cbcc418814610dc057600080fd5b8063a574cea414610c97578063a9cdd60d14610cc4578063ac52e64414610ce4578063b1a6505f14610d04578063b4bc159a14610d3457600080fd5b806394d216d6116101e2578063a035b1fe116101a6578063a035b1fe14610c24578063a0712d6814610c3a578063a217fddf14610c4d578063a22cb46514610c62578063a475b5dd14610c8257600080fd5b806394d216d614610b825780639556483714610ba257806395d89b4114610bc25780639a9e2e4a14610bd75780639ec00c9514610bf757600080fd5b80638984cbb0116102295780638984cbb014610abe5780638ada6b0f14610ade5780638da5cb5b14610afe57806391b7f5ed14610b1c57806391d1485414610b3c57600080fd5b80636f8b44b014610a1b57806370a0823114610a3b578063715018a614610a5b57806372abc8b714610a705780637cb6475914610a9e57600080fd5b80633ccfd60b116103815780634f6ccce7116102fe57806361728f39116102c257806361728f391461095a57806361d027b31461098e5780636352211e146109ae578063650b00f6146109ce5780636ba4c138146109fb57600080fd5b80634f6ccce7146108ce5780635146ea0e146108ee57806353f8bb9a1461090e57806354214f69146109245780635e5f3ce41461094357600080fd5b8063453c231011610345578063453c23101461084257806349a5980a146108585780634aa0acc0146108785780634e6fd6c4146108985780634f09cd52146108ae57600080fd5b80633ccfd60b146107a05780633ef628a3146107b557806340a9c8df146107d557806342842e0e146107f5578063438b63001461081557600080fd5b806323b872dd1161040f5780632f2ff15d116103d35780632f2ff15d146107095780632f745c59146107295780633281fa3f14610749578063334d6e8b1461076057806336568abe1461078057600080fd5b806323b872dd14610642578063248a9ca3146106625780632799cde0146106925780632cba8123146106b25780632eb4a7ab146106f357600080fd5b8063095ea7b311610456578063095ea7b31461058a57806309c1ba2e146105ac57806312b40a9f146105ed57806318160ddd1461060d5780631fe543e31461062257600080fd5b806301ffc9a71461049357806306a9a164146104c957806306fdde03146104f6578063081812fc1461051857806309308e5d14610545575b600080fd5b34801561049f57600080fd5b506104b36104ae36600461478b565b610f52565b6040516104c091906147b6565b60405180910390f35b3480156104d557600080fd5b506020546104e9906001600160a01b031681565b6040516104c09190614806565b34801561050257600080fd5b5061050b610f63565b6040516104c09190614874565b34801561052457600080fd5b50610538610533366004614896565b610ff5565b6040516104c091906148d1565b34801561055157600080fd5b5061057d6105603660046148f3565b601160209081526000928352604080842090915290825290205481565b6040516104c09190614936565b34801561059657600080fd5b506105aa6105a5366004614944565b611041565b005b3480156105b857600080fd5b506105e07f000000000000000000000000000000000000000000000000000000000000000081565b6040516104c09190614987565b3480156105f957600080fd5b506105aa610608366004614995565b6110c7565b34801561061957600080fd5b5061057d611102565b34801561062e57600080fd5b506105aa61063d366004614ab8565b61111e565b34801561064e57600080fd5b506105aa61065d366004614b06565b611199565b34801561066e57600080fd5b5061057d61067d366004614896565b60009081526013602052604090206001015490565b34801561069e57600080fd5b506105aa6106ad366004614896565b6111d0565b3480156106be57600080fd5b506105386106cd366004614b56565b60106020908152600092835260408084209091529082529020546001600160a01b031681565b3480156106ff57600080fd5b5061057d601c5481565b34801561071557600080fd5b506105aa6107243660046148f3565b611228565b34801561073557600080fd5b5061057d610744366004614944565b61124d565b34801561075557600080fd5b5060165442116104b3565b34801561076c57600080fd5b506105aa61077b366004614bca565b6112da565b34801561078c57600080fd5b506105aa61079b3660046148f3565b61192b565b3480156107ac57600080fd5b506105aa61195d565b3480156107c157600080fd5b506105aa6107d0366004614c3a565b6119f6565b3480156107e157600080fd5b506105aa6107f0366004614896565b611bcf565b34801561080157600080fd5b506105aa610810366004614b06565b611c27565b34801561082157600080fd5b50610835610830366004614995565b611c42565b6040516104c09190614cf3565b34801561084e57600080fd5b5061057d601a5481565b34801561086457600080fd5b506105aa610873366004614d17565b611cfb565b34801561088457600080fd5b506105aa610893366004614b56565b611d2e565b3480156108a457600080fd5b5061053861dead81565b3480156108ba57600080fd5b506105aa6108c9366004614995565b611d83565b3480156108da57600080fd5b5061057d6108e9366004614896565b611de2565b3480156108fa57600080fd5b506105aa610909366004614b56565b611e5c565b34801561091a57600080fd5b5061057d60175481565b34801561093057600080fd5b50601b546104b390610100900460ff1681565b34801561094f57600080fd5b5060175442116104b3565b34801561096657600080fd5b5061057d7f000000000000000000000000000000000000000000000000000000000000000081565b34801561099a57600080fd5b50601554610538906001600160a01b031681565b3480156109ba57600080fd5b506105386109c9366004614896565b611ea7565b3480156109da57600080fd5b5061057d6109e9366004614896565b600f6020526000908152604090205481565b348015610a0757600080fd5b506105aa610a16366004614d83565b611ebe565b348015610a2757600080fd5b506105aa610a36366004614896565b611fc7565b348015610a4757600080fd5b5061057d610a56366004614995565b611fe5565b348015610a6757600080fd5b506105aa61206e565b348015610a7c57600080fd5b506104b3610a8b366004614896565b6000908152600f60205260409020541590565b348015610aaa57600080fd5b506105aa610ab9366004614896565b6120a4565b348015610aca57600080fd5b506105aa610ad9366004614896565b6120c2565b348015610aea57600080fd5b506021546104e9906001600160a01b031681565b348015610b0a57600080fd5b50600d546001600160a01b0316610538565b348015610b2857600080fd5b506105aa610b37366004614896565b6120e0565b348015610b4857600080fd5b506104b3610b573660046148f3565b60009182526013602090815260408084206001600160a01b0393909316845291905290205460ff1690565b348015610b8e57600080fd5b506105aa610b9d3660046148f3565b6120fe565b348015610bae57600080fd5b5061057d610bbd366004614896565b612157565b348015610bce57600080fd5b5061050b6121f1565b348015610be357600080fd5b506022546104e9906001600160a01b031681565b348015610c0357600080fd5b5061057d610c12366004614995565b601e6020526000908152604090205481565b348015610c3057600080fd5b5061057d60195481565b6105aa610c48366004614896565b612200565b348015610c5957600080fd5b5061057d600081565b348015610c6e57600080fd5b506105aa610c7d366004614dcb565b6122fd565b348015610c8e57600080fd5b506105aa612395565b348015610ca357600080fd5b50610cb7610cb2366004614896565b6123f6565b6040516104c09190614ef9565b348015610cd057600080fd5b506105aa610cdf366004614995565b612631565b348015610cf057600080fd5b506105aa610cff366004614f0a565b61266c565b348015610d1057600080fd5b506104b3610d1f366004614995565b600e6020526000908152604090205460ff1681565b348015610d4057600080fd5b5061057d60145481565b348015610d5657600080fd5b5061057d60165481565b348015610d6c57600080fd5b506105aa610d7b366004615012565b612753565b348015610d8c57600080fd5b5061050b610d9b366004614896565b612791565b348015610dac57600080fd5b5061057d610dbb366004614995565b612b37565b348015610dcc57600080fd5b506105aa610ddb366004614d17565b612b69565b6105aa610dee366004615085565b612b95565b348015610dff57600080fd5b506105aa610e0e366004614c3a565b612db8565b348015610e1f57600080fd5b506105aa610e2e3660046148f3565b6130cd565b348015610e3f57600080fd5b5061057d60185481565b348015610e5557600080fd5b506105aa610e64366004614896565b6130f2565b348015610e7557600080fd5b506105aa610e84366004614896565b613110565b348015610e9557600080fd5b506104b3610ea43660046150d5565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610ede57600080fd5b50601f546104e9906001600160a01b031681565b348015610efe57600080fd5b506105aa610f0d366004614995565b61312e565b348015610f1e57600080fd5b506105aa610f2d366004614995565b613169565b348015610f3e57600080fd5b506105aa610f4d366004614c3a565b6131c2565b6000610f5d82613545565b92915050565b606060018054610f729061510d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9e9061510d565b8015610feb5780601f10610fc057610100808354040283529160200191610feb565b820191906000526020600020905b815481529060010190602001808311610fce57829003601f168201915b5050505050905090565b60006110008261356a565b6110255760405162461bcd60e51b815260040161101c9061515b565b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061104c82611ea7565b9050806001600160a01b0316836001600160a01b031614156110805760405162461bcd60e51b815260040161101c9061518b565b336001600160a01b038216148061109c575061109c8133610ea4565b6110b85760405162461bcd60e51b815260040161101c906151bb565b6110c283836135a1565b505050565b600080516020615dfe8339815191526110df8161360f565b50602180546001600160a01b0319166001600160a01b0392909216919091179055565b600061110c613619565b60045461111991906151e1565b905090565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461118b57337f000000000000000000000000000000000000000000000000000000000000000060405163073e64fd60e21b815260040161101c9291906151f8565b6111958282613679565b5050565b6000818152600f6020526040902054156111c55760405162461bcd60e51b815260040161101c9061522e565b6110c28383836136c3565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba46111fa8161360f565b6112038261356a565b61121f5760405162461bcd60e51b815260040161101c90615256565b611195826136f4565b6000828152601360205260409020600101546112438161360f565b6110c28383613804565b60008060005b6004548110156112c1576112668161356a565b801561128b575061127681611ea7565b6001600160a01b0316856001600160a01b0316145b156112af57838214156112a1579150610f5d9050565b816112ab81615266565b9250505b806112b981615266565b915050611253565b5060405162461bcd60e51b815260040161101c9061529b565b83336112e582611ea7565b6001600160a01b03161461130c576040516349e27cff60e01b815260040160405180910390fd5b601f54604051627eeac760e11b815283916001600160a01b03169062fdd58e9061133c90339085906004016152ab565b60206040518083038186803b15801561135457600080fd5b505afa158015611368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138c91906152d1565b6113a9576040516349e27cff60e01b815260040160405180910390fd5b8285858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601f5460405163c19a4ef560e01b81526001600160a01b03909116925063c19a4ef59150611410908590600401614936565b60006040518083038186803b15801561142857600080fd5b505afa15801561143c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611464919081019061534a565b60405160200161147491906153a7565b604051602081830303815290604052805190602001208160405160200161149b91906153a7565b60405160208183030381529060405280519060200120146114cf57604051631e4cbc7f60e21b815260040160405180910390fd5b601f5460405163adc0f74560e01b815286918a916001600160a01b039091169063adc0f74590611503908590600401614936565b60206040518083038186803b15801561151b57600080fd5b505afa15801561152f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155391906152d1565b6000828152601d6020526040902060090154101561158457604051636e7e5ecf60e01b815260040160405180910390fd5b600260125414156115a75760405162461bcd60e51b815260040161101c906153e7565b60026012556040516000906115c2908b908b9060200161540a565b60408051601f19818403018152828252805160209182012060008f8152601d835292909220919350909183916115f89101615417565b604051602081830303815290604052805190602001201415611642576004810154156116365760405162461bcd60e51b815260040161101c90615447565b60048101899055611877565b816040516020016116529061546b565b60405160208183030381529060405280519060200120141561169c576003810154156116905760405162461bcd60e51b815260040161101c90615447565b60038101899055611877565b816040516020016116ac90615476565b6040516020818303038152906040528051906020012014156116f6576005810154156116ea5760405162461bcd60e51b815260040161101c90615447565b60058101899055611877565b81604051602001611706906154a6565b604051602081830303815290604052805190602001201415611750576002810154156117445760405162461bcd60e51b815260040161101c90615447565b60028101899055611877565b81604051602001611760906154c8565b6040516020818303038152906040528051906020012014156117aa5760068101541561179e5760405162461bcd60e51b815260040161101c90615447565b60068101899055611877565b816040516020016117ba906154d3565b604051602081830303815290604052805190602001201415611804576007810154156117f85760405162461bcd60e51b815260040161101c90615447565b60078101899055611877565b81604051602001611814906154fc565b60405160208183030381529060405280519060200120141561185e576008810154156118525760405162461bcd60e51b815260040161101c90615447565b60088101899055611877565b604051631e4cbc7f60e21b815260040160405180910390fd5b601f546001600160a01b0316639eef4aa68a6001336040518463ffffffff1660e01b81526004016118aa9392919061551c565b600060405180830381600087803b1580156118c457600080fd5b505af11580156118d8573d6000803e3d6000fd5b505050508b7f913887fd0b468ebff22eac13535c8b5a656d89040bff7d16d7d4531bf27030d68c8c8c60405161191093929190615567565b60405180910390a25050600160125550505050505050505050565b6001600160a01b03811633146119535760405162461bcd60e51b815260040161101c906155e5565b61119582826138a6565b600080516020615dfe8339815191526119758161360f565b6015546040516000916001600160a01b0316904790611993906155f5565b60006040518083038185875af1925050503d80600081146119d0576040519150601f19603f3d011682016040523d82523d6000602084013e6119d5565b606091505b50509050806111955760405162461bcd60e51b815260040161101c9061561a565b8233611a0182611ea7565b6001600160a01b031614611a28576040516349e27cff60e01b815260040160405180910390fd5b8282600082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509394505050505b8151811015611ae3576000828281518110611a8257611a8261562a565b01602001516001600160f81b0319169050601160f91b811480611ab25750601760fa1b6001600160f81b03198216145b15611ad057604051630ec0325960e21b815260040160405180910390fd5b5080611adb81615266565b915050611a65565b50600086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508c8152601d6020526040908190209051949550611b3f946001909101935091506156ae9050565b604051809103902081805190602001201415611b6e57604051632a9ffab760e21b815260040160405180910390fd5b6000888152601d60205260409020611b8a9060010188886146d0565b50877f1d83c2282d074aad212f8c5d02271066bf42c603a85c4c9e4f07d1eb8c1998218888604051611bbd9291906156ba565b60405180910390a25050505050505050565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba4611bf98161360f565b611c028261356a565b611c1e5760405162461bcd60e51b815260040161101c90615256565b61119582613929565b6110c283838360405180602001604052806000815250612753565b60606000611c4f83611fe5565b905080611c705760408051600080825260208201909252905b509392505050565b60008167ffffffffffffffff811115611c8b57611c8b6149b6565b604051908082528060200260200182016040528015611cb4578160200160208202803683370190505b50905060005b82811015611c6857611ccc858261124d565b828281518110611cde57611cde61562a565b602090810291909101015280611cf381615266565b915050611cba565b600080516020615dfe833981519152611d138161360f565b50601b80549115156101000261ff0019909216919091179055565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba4611d588161360f565b6000838152601d602052604081206009018054849290611d799084906151e1565b9091555050505050565b600080516020615dfe833981519152611d9b8161360f565b600060145411611dbd5760405162461bcd60e51b815260040161101c906156e5565b611dd98260145460405180602001604052806000815250613a96565b50506000601455565b6000611dec611102565b8210611e0a5760405162461bcd60e51b815260040161101c9061529b565b6000805b600454811015611e5557611e218161356a565b15611e435783821415611e35579392505050565b81611e3f81615266565b9250505b80611e4d81615266565b915050611e0e565b5050919050565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba4611e868161360f565b6000838152601d602052604081206009018054849290611d799084906156f5565b6000806000611eb584613ab6565b50949350505050565b60026012541415611ee15760405162461bcd60e51b815260040161101c906153e7565b60026012556017544211611f075760405162461bcd60e51b815260040161101c90615256565b60005b81811015611fa3576020546001600160a01b03166323b872dd3361dead868686818110611f3957611f3961562a565b905060200201356040518463ffffffff1660e01b8152600401611f5e9392919061570d565b600060405180830381600087803b158015611f7857600080fd5b505af1158015611f8c573d6000803e3d6000fd5b505050508080611f9b90615266565b915050611f0a565b50611fbe336040805160208101909152600081528390613a96565b50506001601255565b600080516020615dfe833981519152611fdf8161360f565b50601855565b60006001600160a01b03821661200d5760405162461bcd60e51b815260040161101c90615758565b6000805b600454811015612067576120248161356a565b156120575761203281611ea7565b6001600160a01b0316846001600160a01b031614156120575761205482615266565b91505b61206081615266565b9050612011565b5092915050565b600d546001600160a01b031633146120985760405162461bcd60e51b815260040161101c9061579a565b6120a26000613b08565b565b600080516020615dfe8339815191526120bc8161360f565b50601c55565b600080516020615dfe8339815191526120da8161360f565b50601755565b600080516020615dfe8339815191526120f88161360f565b50601955565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba46121288161360f565b6121318361356a565b61214d5760405162461bcd60e51b815260040161101c90615256565b6110c28383613b5a565b60006121628261356a565b61217e5760405162461bcd60e51b815260040161101c9061515b565b60006009600061218d85613ced565b815260200190815260200160002054905080600014156121bf5760405162461bcd60e51b815260040161101c906157cc565b80836040516020016121d29291906157dc565b60408051601f1981840301815291905280516020909101209392505050565b606060028054610f729061510d565b60175442116122215760405162461bcd60e51b815260040161101c90615256565b6018548161222d611102565b61223791906156f5565b106122545760405162461bcd60e51b815260040161101c90615802565b6019546122619082615812565b3410156122805760405162461bcd60e51b815260040161101c90615849565b601a54336000908152601e602052604090205461229e9083906156f5565b106122bb5760405162461bcd60e51b815260040161101c90615871565b336000908152601e6020526040812080548392906122da9084906156f5565b909155506122fa9050338260405180602001604052806000815250613a96565b50565b6001600160a01b0382163314156123265760405162461bcd60e51b815260040161101c906158a0565b3360008181526006602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31906123899085906147b6565b60405180910390a35050565b600080516020615dfe8339815191526123ad8161360f565b6123b5613d37565b7f15120e52505e619cbf6c2af910d5cf7f9ee1befa55801b078c33e93880b2d6096123de611102565b6040516123eb9190614936565b60405180910390a150565b61245c60405180610180016040528060608152602001606081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600081525090565b6124658261356a565b6124815760405162461bcd60e51b815260040161101c90615256565b6000828152601d602052604090819020815161018081019092528054829082906124aa9061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546124d69061510d565b80156125235780601f106124f857610100808354040283529160200191612523565b820191906000526020600020905b81548152906001019060200180831161250657829003601f168201915b5050505050815260200160018201805461253c9061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546125689061510d565b80156125b55780601f1061258a576101008083540402835291602001916125b5565b820191906000526020600020905b81548152906001019060200180831161259857829003601f168201915b505050918352505060028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c0820152600882015460e08201526009820154610100820152600a82015460ff161515610120820152600b909101546101409091015292915050565b600080516020615dfe8339815191526126498161360f565b50601f80546001600160a01b0319166001600160a01b0392909216919091179055565b600d546001600160a01b031633146126965760405162461bcd60e51b815260040161101c9061579a565b8281146126b55760405162461bcd60e51b815260040161101c906158ce565b60005b8381101561274c578282828181106126d2576126d261562a565b90506020020160208101906126e79190614d17565b600e60008787858181106126fd576126fd61562a565b90506020020160208101906127129190614995565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558061274481615266565b9150506126b8565b5050505050565b6000828152600f60205260409020541561277f5760405162461bcd60e51b815260040161101c9061522e565b61278b84848484613ec4565b50505050565b601b54606090610100900460ff1661282757602154604051632914130560e01b81526001600160a01b03909116906329141305906127d3908590600401614936565b60006040518083038186803b1580156127eb57600080fd5b505afa1580156127ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f5d919081019061534a565b6128308261356a565b61284c5760405162461bcd60e51b815260040161101c90615256565b6000828152601d6020526040808220815161018081019092528054829082906128749061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546128a09061510d565b80156128ed5780601f106128c2576101008083540402835291602001916128ed565b820191906000526020600020905b8154815290600101906020018083116128d057829003601f168201915b505050505081526020016001820180546129069061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546129329061510d565b801561297f5780601f106129545761010080835404028352916020019161297f565b820191906000526020600020905b81548152906001019060200180831161296257829003601f168201915b505050918352505060028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c0820152600882015460e08201526009820154610100820152600a82015460ff161515610120820152600b90910154610140909101529050612a0e836000908152600f60205260409020541590565b15156101408201526022546001600160a01b031663de325b8f612a3085611ea7565b6040518263ffffffff1660e01b8152600401612a4c91906148d1565b60206040518083038186803b158015612a6457600080fd5b505afa158015612a78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9c91906152d1565b6101608201526021546001600160a01b031663f3b95d0384612abd81612157565b846040518463ffffffff1660e01b8152600401612adc939291906158de565b60006040518083038186803b158015612af457600080fd5b505afa158015612b08573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b30919081019061534a565b9392505050565b6001600160a01b0381166000908152601e6020526040812054601a54600191612b5f916151e1565b610f5d91906151e1565b600080516020615dfe833981519152612b818161360f565b50601b805460ff1916911515919091179055565b60026012541415612bb85760405162461bcd60e51b815260040161101c906153e7565b60026012556016544211612bde5760405162461bcd60e51b815260040161101c90615256565b60185483612bea611102565b612bf491906156f5565b10612c115760405162461bcd60e51b815260040161101c90615802565b601954612c1e9084615812565b341015612c3d5760405162461bcd60e51b815260040161101c90615849565b601a54336000908152601e6020526040902054612c5b9085906156f5565b10612c785760405162461bcd60e51b815260040161101c90615871565b600033604051602001612c8b919061593c565b604051602081830303815290604052805190602001209050612ce483838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601c549150849050613ef6565b612d005760405162461bcd60e51b815260040161101c90615969565b336000908152601e602052604081208054869290612d1f9084906156f5565b90915550612d3f9050338560405180602001604052806000815250613a96565b601b5460ff1615612dad57601f546001600160a01b0316633cbf48e933866040518363ffffffff1660e01b8152600401612d7a9291906152ab565b600060405180830381600087803b158015612d9457600080fd5b505af1158015612da8573d6000803e3d6000fd5b505050505b505060016012555050565b8233612dc382611ea7565b6001600160a01b031614612dea576040516349e27cff60e01b815260040160405180910390fd5b60026012541415612e0d5760405162461bcd60e51b815260040161101c906153e7565b60026012556040516000908190612e2a908690869060200161540a565b60408051601f19818403018152828252805160209182012060008a8152601d83529290922091935090918391612e609101615417565b604051602081830303815290604052805190602001201415612e8e5760048101805460009091559250612ffe565b81604051602001612e9e9061546b565b604051602081830303815290604052805190602001201415612ecc5760038101805460009091559250612ffe565b81604051602001612edc90615476565b604051602081830303815290604052805190602001201415612f0a5760058101805460009091559250612ffe565b81604051602001612f1a906154a6565b604051602081830303815290604052805190602001201415612f485760028101805460009091559250612ffe565b81604051602001612f58906154c8565b604051602081830303815290604052805190602001201415612f865760068101805460009091559250612ffe565b81604051602001612f96906154d3565b604051602081830303815290604052805190602001201415612fc45760078101805460009091559250612ffe565b81604051602001612fd4906154fc565b60405160208183030381529060405280519060200120141561185e57600881018054600090915592505b6000831161301e5760405162461bcd60e51b815260040161101c90615994565b601f546001600160a01b031663466e79eb846001336040518463ffffffff1660e01b81526004016130519392919061551c565b600060405180830381600087803b15801561306b57600080fd5b505af115801561307f573d6000803e3d6000fd5b50505050867fd4596d80f81394606eec2500c28df457c069fe45c83d304190e97e0a8061d6b78787866040516130b793929190615567565b60405180910390a2505060016012555050505050565b6000828152601360205260409020600101546130e88161360f565b6110c283836138a6565b600080516020615dfe83398151915261310a8161360f565b50601655565b600080516020615dfe8339815191526131288161360f565b50601a55565b600080516020615dfe8339815191526131468161360f565b50601580546001600160a01b0319166001600160a01b0392909216919091179055565b600d546001600160a01b031633146131935760405162461bcd60e51b815260040161101c9061579a565b6001600160a01b0381166131b95760405162461bcd60e51b815260040161101c906159e7565b6122fa81613b08565b82336131cd82611ea7565b6001600160a01b0316146131f4576040516349e27cff60e01b815260040160405180910390fd5b8282600082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509394505050505b81518110156132af57600082828151811061324e5761324e61562a565b01602001516001600160f81b0319169050601160f91b81148061327e5750601760fa1b6001600160f81b03198216145b1561329c57604051630ec0325960e21b815260040160405180910390fd5b50806132a781615266565b915050613231565b50600086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050506019101561330e5760405163251f56a160e21b815260040160405180910390fd5b6000888152601d602052604090819020905161332a91906156ae565b60405180910390208180519060200120141561335957604051632a9ffab760e21b815260040160405180910390fd5b6000888152601d602052604090206133729088886146d0565b50877f8edfa912e70e283a8ef6d6f52cd1faef9690ff989eff2f11a134e8478ba7b28b8888604051611bbd9291906156ba565b600454600881901c60009081526007602052604090208054600160ff1b60ff84161c17905561278b848484613401565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b600454826134215760405162461bcd60e51b815260040161101c90615a12565b6001600160a01b0384166134475760405162461bcd60e51b815260040161101c90615a45565b60005b838110156134d557600061345e82846156f5565b60405190915081906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46134a66000878387613f0c565b6134c25760405162461bcd60e51b815260040161101c90615a89565b50806134cd81615266565b91505061344a565b50600081815260036020908152604080832080546001600160a01b0319166001600160a01b038916179055600884901c83529082905290208054600160ff1b60ff84161c179055826004600082825461352e91906156f5565b9091555061278b9050600085838684565b3b151590565b60006001600160e01b03198216637965db0b60e01b1480610f5d5750610f5d8261401a565b600881901c6000908152600c6020526040812054600160ff1b60ff84161c161561359657506000919050565b610f5d826004541190565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906135d682611ea7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6122fa8133614085565b6000806008600454901c600161362f91906156f5565b905060005b81811015613674576000818152600c602052604090205461365481614105565b61365e90856156f5565b935050808061366c90615266565b915050613634565b505090565b60008160008151811061368e5761368e61562a565b60209081029190910181015160008581526008835260408082205480835281832083905560099094529020819055915061278b565b6136cd3382614124565b6136e95760405162461bcd60e51b815260040161101c906151bb565b6110c28383836141c5565b336000908152600e602052604090205460ff166137235760405162461bcd60e51b815260040161101c90615acd565b60008181526011602090815260408083203384529091529020541561375a5760405162461bcd60e51b815260040161101c90615b11565b6000818152600f60205260408120546137749060016156f5565b6000838152601060209081526040808320848452825280832080546001600160a01b03191633908117909155868452601183528184209084528252808320849055858352600f90915281208054929350906137ce83615266565b9091555050604051339083907f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264390600090a35050565b60008281526013602090815260408083206001600160a01b038516845290915290205460ff166111955760008281526013602090815260408083206001600160a01b03851684529091529020805460ff191660011790556138623390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526013602090815260408083206001600160a01b038516845290915290205460ff16156111955760008281526013602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b336000908152600e602052604090205460ff166139585760405162461bcd60e51b815260040161101c90615acd565b60008181526011602090815260408083203384529091529020548061398f5760405162461bcd60e51b815260040161101c90615b55565b6000828152600f6020526040902054818114613a055760008381526010602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155868452601183528184209084529091529020829055613a2d565b6000838152601060209081526040808320858452909152902080546001600160a01b03191690555b60008381526011602090815260408083203384528252808320839055858352600f9091528120805491613a5f83615b65565b9091555050604051339084907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a3505050565b600454600b546000828152600a602052604090205561278b8484846133a5565b600080613ac28361356a565b613ade5760405162461bcd60e51b815260040161101c9061515b565b613ae78361435a565b6000818152600360205260409020546001600160a01b031694909350915050565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0381166000908152600e602052604090205460ff1615613b935760405162461bcd60e51b815260040161101c90615acd565b60008281526011602090815260408083206001600160a01b038516845290915290205480613bd35760405162461bcd60e51b815260040161101c90615bb0565b6000838152600f6020526040902054818114613c495760008481526010602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155878452601183528184209084529091529020829055613c71565b6000848152601060209081526040808320858452909152902080546001600160a01b03191690555b60008481526011602090815260408083206001600160a01b03871684528252808320839055868352600f9091528120805491613cac83615b65565b90915550506040516001600160a01b0384169085907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a350505050565b6000613cf88261356a565b613d145760405162461bcd60e51b815260040161101c9061515b565b600a6000613d2184614366565b8152602001908152602001600020549050919050565b6040516305d3b1d360e41b81526000907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031690635d3b1d3090613e0f907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000907f000000000000000000000000000000000000000000000000000000000000000090600190600401615beb565b602060405180830381600087803b158015613e2957600080fd5b505af1158015613e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6191906152d1565b90507f76421cb080d40e8a03ba462b500012451ba59bdebc46694dc458807c1d754b6281604051613e929190614936565b60405180910390a1600b54600082815260086020526040902055600b8054906000613ebc83615266565b919050555050565b613ece3383614124565b613eea5760405162461bcd60e51b815260040161101c906151bb565b61278b84848484614373565b600082613f0385846143a6565b14949350505050565b60006001600160a01b0384163b1561400e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613f50903390899088908890600401615c37565b602060405180830381600087803b158015613f6a57600080fd5b505af1925050508015613f9a575060408051601f3d908101601f19168201909252613f9791810190615c7c565b60015b613ff4573d808015613fc8576040519150601f19603f3d011682016040523d82523d6000602084013e613fcd565b606091505b508051613fec5760405162461bcd60e51b815260040161101c90615a89565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050614012565b5060015b949350505050565b60006001600160e01b031982166380ac58cd60e01b148061404b57506001600160e01b03198216635b5e139f60e01b145b8061406657506001600160e01b0319821663780e9d6360e01b145b80610f5d57506301ffc9a760e01b6001600160e01b0319831614610f5d565b60008281526013602090815260408083206001600160a01b038516845290915290205460ff16611195576140c3816001600160a01b03166014614412565b6140ce836020614412565b6040516020016140df929190615c9d565b60408051601f198184030181529082905262461bcd60e51b825261101c91600401614874565b60005b811561411f57600019820190911690600101614108565b919050565b600061412f8261356a565b61414b5760405162461bcd60e51b815260040161101c90615d1e565b600061415683611ea7565b9050806001600160a01b0316846001600160a01b031614806141915750836001600160a01b031661418684610ff5565b6001600160a01b0316145b8061401257506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff16614012565b6000806141d183613ab6565b91509150846001600160a01b0316826001600160a01b0316146142065760405162461bcd60e51b815260040161101c90615d4b565b6001600160a01b03841661422c5760405162461bcd60e51b815260040161101c90615d7d565b6142376000846135a1565b60006142448460016156f5565b600881901c600090815260208190526040902054909150600160ff1b60ff83161c16158015614274575060045481105b156142c057600081815260036020908152604080832080546001600160a01b0319166001600160a01b038b16179055600884901c83529082905290208054600160ff1b60ff84161c1790555b600084815260036020526040902080546001600160a01b0319166001600160a01b03871617905581841461431157600884901c60009081526020819052604090208054600160ff1b60ff87161c1790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000610f5d818361458b565b6000610f5d60078361458b565b61437e8484846141c5565b61438a84848484613f0c565b61278b5760405162461bcd60e51b815260040161101c90615a89565b600081815b8451811015611c685760008582815181106143c8576143c861562a565b602002602001015190508083116143ee57600083815260208290526040902092506143ff565b600081815260208490526040902092505b508061440a81615266565b9150506143ab565b60606000614421836002615812565b61442c9060026156f5565b67ffffffffffffffff811115614444576144446149b6565b6040519080825280601f01601f19166020018201604052801561446e576020820181803683370190505b509050600360fc1b816000815181106144895761448961562a565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106144b8576144b861562a565b60200101906001600160f81b031916908160001a90535060006144dc846002615812565b6144e79060016156f5565b90505b600181111561456c577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106145285761452861562a565b1a60f81b82828151811061453e5761453e61562a565b60200101906001600160f81b031916908160001a90535060049490941c9361456581615b65565b90506144ea565b508315612b305760405162461bcd60e51b815260040161101c90615dbf565b600881901c60008181526020849052604081205490919060ff8085169190821890811c80156145d3576145bd8161464e565b60ff168303600885901b17945050505050610f5d565b600084116145f35760405162461bcd60e51b815260040161101c9061515b565b6000199093019260ff9250600091505b506000838152602087905260409020548015614622576145bd8161464e565b600084116146425760405162461bcd60e51b815260040161101c90615ded565b60001990930192614603565b60006040518061012001604052806101008152602001615e1e610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff614697856146b8565b02901c815181106146aa576146aa61562a565b016020015160f81c92915050565b60008082116146c657600080fd5b5060008190031690565b8280546146dc9061510d565b90600052602060002090601f0160209004810192826146fe5760008555614744565b82601f106147175782800160ff19823516178555614744565b82800160010185558215614744579182015b82811115614744578235825591602001919060010190614729565b50614750929150614754565b5090565b5b808211156147505760008155600101614755565b6001600160e01b031981165b81146122fa57600080fd5b8035610f5d81614769565b6000602082840312156147a0576147a0600080fd5b60006140128484614780565b8015155b82525050565b60208101610f5d82846147ac565b6000610f5d6001600160a01b0383166147db565b90565b6001600160a01b031690565b6000610f5d826147c4565b6000610f5d826147e7565b6147b0816147f2565b60208101610f5d82846147fd565b60005b8381101561482f578181015183820152602001614817565b8381111561278b5750506000910152565b600061484a825190565b808452602084019350614861818560208601614814565b601f19601f8201165b9093019392505050565b60208082528101612b308184614840565b80614775565b8035610f5d81614885565b6000602082840312156148ab576148ab600080fd5b6000614012848461488b565b60006001600160a01b038216610f5d565b6147b0816148b7565b60208101610f5d82846148c8565b614775816148b7565b8035610f5d816148df565b6000806040838503121561490957614909600080fd5b6000614915858561488b565b9250506020614926858286016148e8565b9150509250929050565b806147b0565b60208101610f5d8284614930565b6000806040838503121561495a5761495a600080fd5b600061496685856148e8565b92505060206149268582860161488b565b67ffffffffffffffff81166147b0565b60208101610f5d8284614977565b6000602082840312156149aa576149aa600080fd5b600061401284846148e8565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff821117156149f2576149f26149b6565b6040525050565b6000614a0460405190565b905061411f82826149cc565b600067ffffffffffffffff821115614a2a57614a2a6149b6565b5060209081020190565b6000614a47614a4284614a10565b6149f9565b83815290506020808201908402830185811115614a6657614a66600080fd5b835b81811015614a8a5780614a7b888261488b565b84525060209283019201614a68565b5050509392505050565b600082601f830112614aa857614aa8600080fd5b8135614012848260208601614a34565b60008060408385031215614ace57614ace600080fd5b6000614ada858561488b565b925050602083013567ffffffffffffffff811115614afa57614afa600080fd5b61492685828601614a94565b600080600060608486031215614b1e57614b1e600080fd5b6000614b2a86866148e8565b9350506020614b3b868287016148e8565b9250506040614b4c8682870161488b565b9150509250925092565b60008060408385031215614b6c57614b6c600080fd5b6000614966858561488b565b60008083601f840112614b8d57614b8d600080fd5b50813567ffffffffffffffff811115614ba857614ba8600080fd5b602083019150836001820283011115614bc357614bc3600080fd5b9250929050565b60008060008060608587031215614be357614be3600080fd5b6000614bef878761488b565b945050602085013567ffffffffffffffff811115614c0f57614c0f600080fd5b614c1b87828801614b78565b93509350506040614c2e8782880161488b565b91505092959194509250565b600080600060408486031215614c5257614c52600080fd5b6000614c5e868661488b565b935050602084013567ffffffffffffffff811115614c7e57614c7e600080fd5b614c8a86828701614b78565b92509250509250925092565b6000614ca28383614930565b505060200190565b6000614cb4825190565b80845260209384019383018060005b83811015614ce8578151614cd78882614c96565b975060208301925050600101614cc3565b509495945050505050565b60208082528101612b308184614caa565b801515614775565b8035610f5d81614d04565b600060208284031215614d2c57614d2c600080fd5b60006140128484614d0c565b60008083601f840112614d4d57614d4d600080fd5b50813567ffffffffffffffff811115614d6857614d68600080fd5b602083019150836020820283011115614bc357614bc3600080fd5b60008060208385031215614d9957614d99600080fd5b823567ffffffffffffffff811115614db357614db3600080fd5b614dbf85828601614d38565b92509250509250929050565b60008060408385031215614de157614de1600080fd5b6000614ded85856148e8565b925050602061492685828601614d0c565b805161018080845260009190840190614e178282614840565b91505060208301518482036020860152614e318282614840565b9150506040830151614e466040860182614930565b506060830151614e596060860182614930565b506080830151614e6c6080860182614930565b5060a0830151614e7f60a0860182614930565b5060c0830151614e9260c0860182614930565b5060e0830151614ea560e0860182614930565b50610100830151614eba610100860182614930565b50610120830151614ecf610120860182614930565b50610140830151614ee46101408601826147ac565b50610160830151611c68610160860182614930565b60208082528101612b308184614dfe565b60008060008060408587031215614f2357614f23600080fd5b843567ffffffffffffffff811115614f3d57614f3d600080fd5b614f4987828801614d38565b9450945050602085013567ffffffffffffffff811115614f6b57614f6b600080fd5b614f7787828801614d38565b95989497509550505050565b600067ffffffffffffffff821115614f9d57614f9d6149b6565b601f19601f83011660200192915050565b82818337506000910152565b6000614fc8614a4284614f83565b905082815260208101848484011115614fe357614fe3600080fd5b611c68848285614fae565b600082601f83011261500257615002600080fd5b8135614012848260208601614fba565b6000806000806080858703121561502b5761502b600080fd5b600061503787876148e8565b9450506020615048878288016148e8565b93505060406150598782880161488b565b925050606085013567ffffffffffffffff81111561507957615079600080fd5b614c2e87828801614fee565b60008060006040848603121561509d5761509d600080fd5b60006150a9868661488b565b935050602084013567ffffffffffffffff8111156150c9576150c9600080fd5b614c8a86828701614d38565b600080604083850312156150eb576150eb600080fd5b600061491585856148e8565b634e487b7160e01b600052602260045260246000fd5b60028104600182168061512157607f821691505b60208210811415615134576151346150f7565b50919050565b60078152600060208201662165786973747360c81b815291505b5060200190565b60208082528101610f5d8161513a565b600981526000602082016808585c1c1c9bdd985b60ba1b81529150615154565b60208082528101610f5d8161516b565b600981526000602082016808585c1c1c9bdd995960ba1b81529150615154565b60208082528101610f5d8161519b565b634e487b7160e01b600052601160045260246000fd5b6000828210156151f3576151f36151cb565b500390565b6040810161520682856148c8565b612b3060208301846148c8565b60048152600060208201633133333760e01b81529150615154565b60208082528101610f5d81615213565b60018152600060208201600360fc1b81529150615154565b60208082528101610f5d8161523e565b600060001982141561527a5761527a6151cb565b5060010190565b600381526000602082016237b7b160e91b81529150615154565b60208082528101610f5d81615281565b604081016152b982856148c8565b612b306020830184614930565b8051610f5d81614885565b6000602082840312156152e6576152e6600080fd5b600061401284846152c6565b6000615300614a4284614f83565b90508281526020810184848401111561531b5761531b600080fd5b611c68848285614814565b600082601f83011261533a5761533a600080fd5b81516140128482602086016152f2565b60006020828403121561535f5761535f600080fd5b815167ffffffffffffffff81111561537957615379600080fd5b61401284828501615326565b600061538f825190565b61539d818560208601614814565b9290920192915050565b6000612b308284615385565b601f81526000602082017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529150615154565b60208082528101610f5d816153b3565b6000615404838584614fae565b50500190565b60006140128284866153f7565b652ba2a0a827a760d11b8152600060068201610f5d565b60028152600060208201611c9b60f11b81529150615154565b60208082528101610f5d8161542e565b631211505160e21b815260005b5060040190565b6000610f5d82615457565b6420a926a7a960d91b8152600060058201610f5d565b69109050d2d1d493d5539160b21b815260005b50600a0190565b6000610f5d8261548c565b692320a1a2afa0a926a7a960b11b8152600061549f565b6000610f5d826154b1565b6622aca2aba2a0a960c91b8152600060078201610f5d565b634d49534360e01b81526000615464565b6000610f5d826154eb565b6000610f5d6147d88381565b6147b081615507565b6060810161552a8286614930565b6155376020830185615513565b61401260408301846148c8565b818352600060208401935061555a838584614fae565b601f19601f84011661486a565b60408082528101615579818587615544565b90506140126020830184614930565b602f81526000602082017f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636581527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015291505b5060400190565b60208082528101610f5d81615588565b6000610f5d826147d8565b600381526000602082016239393960e81b81529150615154565b60208082528101610f5d81615600565b634e487b7160e01b600052603260045260246000fd5b6000815461564d8161510d565b6001821680156156645760018114615675576156a5565b60ff198316865281860193506156a5565b60008581526020902060005b8381101561569d57815488820152600190910190602001615681565b838801955050505b50505092915050565b6000612b308284615640565b60208082528101614012818486615544565b6002815260006020820161363960f01b81529150615154565b60208082528101610f5d816156cc565b60008219821115615708576157086151cb565b500190565b6060810161571b82866148c8565b61572860208301856148c8565b6140126040830184614930565b600c81526000602082016b7a65726f206164647265737360a01b81529150615154565b60208082528101610f5d81615735565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657291019081526000615154565b60208082528101610f5d81615768565b600b81526000602082016a08599d5b1b199a5b1b195960aa1b81529150615154565b60208082528101610f5d816157aa565b604081016152b98285614930565b60018152600060208201603960f81b81529150615154565b60208082528101610f5d816157ea565b600081600019048311821515161561582c5761582c6151cb565b500290565b60018152600060208201603160f81b81529150615154565b60208082528101610f5d81615831565b60018152600060208201601960f91b81529150615154565b60208082528101610f5d81615859565b600881526000602082016721617070726f766560c01b81529150615154565b60208082528101610f5d81615881565b6007815260006020820166042d8cadccee8d60cb1b81529150615154565b60208082528101610f5d816158b0565b606081016158ec8286614930565b6158f96020830185614930565b818103604083015261590b8184614dfe565b95945050505050565b6000610f5d8260601b90565b6000610f5d82615914565b6147b0615937826148b7565b615920565b6000615948828461592b565b50601401919050565b60018152600060208201600d60fa1b81529150615154565b60208082528101610f5d81615951565b60048152600060208201633639363960e01b81529150615154565b60208082528101610f5d81615979565b602681526000602082017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015291506155de565b60208082528101610f5d816159a4565b60048152600060208201637a65726f60e01b81529150615154565b60208082528101610f5d816159f7565b600c81526000602082016b217a65726f6164647265737360a01b81529150615154565b60208082528101610f5d81615a22565b600f81526000602082017f214552433732315265636569766572000000000000000000000000000000000081529150615154565b60208082528101610f5d81615a55565b601181526000602082017f43616e6e6f7420757064617465206d617000000000000000000000000000000081529150615154565b60208082528101610f5d81615a99565b601b81526000602082017f494420616c7265616479206c6f636b65642062792063616c6c6572000000000081529150615154565b60208082528101610f5d81615add565b601781526000602082017f4944206e6f74206c6f636b65642062792063616c6c657200000000000000000081529150615154565b60208082528101610f5d81615b21565b600081615b7457615b746151cb565b506000190190565b600d81526000602082017f4944206e6f74206c6f636b65640000000000000000000000000000000000000081529150615154565b60208082528101610f5d81615b7c565b61ffff81166147b0565b63ffffffff81166147b0565b600061ffff8216610f5d565b6147b081615bd6565b60a08101615bf98288614930565b615c066020830187614977565b615c136040830186615bc0565b615c206060830185615bca565b615c2d6080830184615be2565b9695505050505050565b60808101615c4582876148c8565b615c5260208301866148c8565b615c5f6040830185614930565b8181036060830152615c2d8184614840565b8051610f5d81614769565b600060208284031215615c9157615c91600080fd5b60006140128484615c71565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526017016000615ccf8285615385565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000815260110191506140128284615385565b600681526000602082016508595e1a5cdd60d21b81529150615154565b60208082528101610f5d81615d01565b60068152600060208201653737ba37bbb760d11b81529150615154565b60208082528101610f5d81615d2e565b600b81526000602082016a7a65726f6164647265737360a81b81529150615154565b60208082528101610f5d81615d5b565b60208082527f537472696e67733a20686578206c656e67746820696e73756666696369656e7491019081526000615154565b60208082528101610f5d81615d8d565b60078152600060208201662165786973745360c81b81529150615154565b60208082528101610f5d81615dcf56feb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212200a69d5a5a7edc680d1e1a299af104003cfb32e049d1009510bb21d5ab5ecdf6864736f6c63430008090033000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699098af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000001850000000000000000000000000e223db582e3fc2c47ba39f67a1e55b7a75f09fd0000000000000000000000005e2454f33c3da3aa30eabc502255f66a6d72adc8000000000000000000000000e9b41d92c64b4b088a6ddf55057f60195b90e09f000000000000000000000000bd24a76f4135f930f5c49f6c30e0e30a61b97537
Deployed Bytecode
0x60806040526004361061048e5760003560e01c80636f8b44b011610265578063a574cea411610154578063d2cab056116100d1578063e268e4d311610095578063f0f442601161006f578063f0f4426014610ef2578063f2fde38b14610f12578063fe55932a14610f3257600080fd5b8063e268e4d314610e69578063e985e9c514610e89578063ea07e68a14610ed257600080fd5b8063d2cab05614610de0578063d50efd7014610df3578063d547741f14610e13578063d5abeb0114610e33578063d6257bb814610e4957600080fd5b8063b7b2040411610118578063b7b2040414610d4a578063b88d4fde14610d60578063c87b56dd14610d80578063ca2eb5ae14610da0578063cbcc418814610dc057600080fd5b8063a574cea414610c97578063a9cdd60d14610cc4578063ac52e64414610ce4578063b1a6505f14610d04578063b4bc159a14610d3457600080fd5b806394d216d6116101e2578063a035b1fe116101a6578063a035b1fe14610c24578063a0712d6814610c3a578063a217fddf14610c4d578063a22cb46514610c62578063a475b5dd14610c8257600080fd5b806394d216d614610b825780639556483714610ba257806395d89b4114610bc25780639a9e2e4a14610bd75780639ec00c9514610bf757600080fd5b80638984cbb0116102295780638984cbb014610abe5780638ada6b0f14610ade5780638da5cb5b14610afe57806391b7f5ed14610b1c57806391d1485414610b3c57600080fd5b80636f8b44b014610a1b57806370a0823114610a3b578063715018a614610a5b57806372abc8b714610a705780637cb6475914610a9e57600080fd5b80633ccfd60b116103815780634f6ccce7116102fe57806361728f39116102c257806361728f391461095a57806361d027b31461098e5780636352211e146109ae578063650b00f6146109ce5780636ba4c138146109fb57600080fd5b80634f6ccce7146108ce5780635146ea0e146108ee57806353f8bb9a1461090e57806354214f69146109245780635e5f3ce41461094357600080fd5b8063453c231011610345578063453c23101461084257806349a5980a146108585780634aa0acc0146108785780634e6fd6c4146108985780634f09cd52146108ae57600080fd5b80633ccfd60b146107a05780633ef628a3146107b557806340a9c8df146107d557806342842e0e146107f5578063438b63001461081557600080fd5b806323b872dd1161040f5780632f2ff15d116103d35780632f2ff15d146107095780632f745c59146107295780633281fa3f14610749578063334d6e8b1461076057806336568abe1461078057600080fd5b806323b872dd14610642578063248a9ca3146106625780632799cde0146106925780632cba8123146106b25780632eb4a7ab146106f357600080fd5b8063095ea7b311610456578063095ea7b31461058a57806309c1ba2e146105ac57806312b40a9f146105ed57806318160ddd1461060d5780631fe543e31461062257600080fd5b806301ffc9a71461049357806306a9a164146104c957806306fdde03146104f6578063081812fc1461051857806309308e5d14610545575b600080fd5b34801561049f57600080fd5b506104b36104ae36600461478b565b610f52565b6040516104c091906147b6565b60405180910390f35b3480156104d557600080fd5b506020546104e9906001600160a01b031681565b6040516104c09190614806565b34801561050257600080fd5b5061050b610f63565b6040516104c09190614874565b34801561052457600080fd5b50610538610533366004614896565b610ff5565b6040516104c091906148d1565b34801561055157600080fd5b5061057d6105603660046148f3565b601160209081526000928352604080842090915290825290205481565b6040516104c09190614936565b34801561059657600080fd5b506105aa6105a5366004614944565b611041565b005b3480156105b857600080fd5b506105e07f000000000000000000000000000000000000000000000000000000000000018581565b6040516104c09190614987565b3480156105f957600080fd5b506105aa610608366004614995565b6110c7565b34801561061957600080fd5b5061057d611102565b34801561062e57600080fd5b506105aa61063d366004614ab8565b61111e565b34801561064e57600080fd5b506105aa61065d366004614b06565b611199565b34801561066e57600080fd5b5061057d61067d366004614896565b60009081526013602052604090206001015490565b34801561069e57600080fd5b506105aa6106ad366004614896565b6111d0565b3480156106be57600080fd5b506105386106cd366004614b56565b60106020908152600092835260408084209091529082529020546001600160a01b031681565b3480156106ff57600080fd5b5061057d601c5481565b34801561071557600080fd5b506105aa6107243660046148f3565b611228565b34801561073557600080fd5b5061057d610744366004614944565b61124d565b34801561075557600080fd5b5060165442116104b3565b34801561076c57600080fd5b506105aa61077b366004614bca565b6112da565b34801561078c57600080fd5b506105aa61079b3660046148f3565b61192b565b3480156107ac57600080fd5b506105aa61195d565b3480156107c157600080fd5b506105aa6107d0366004614c3a565b6119f6565b3480156107e157600080fd5b506105aa6107f0366004614896565b611bcf565b34801561080157600080fd5b506105aa610810366004614b06565b611c27565b34801561082157600080fd5b50610835610830366004614995565b611c42565b6040516104c09190614cf3565b34801561084e57600080fd5b5061057d601a5481565b34801561086457600080fd5b506105aa610873366004614d17565b611cfb565b34801561088457600080fd5b506105aa610893366004614b56565b611d2e565b3480156108a457600080fd5b5061053861dead81565b3480156108ba57600080fd5b506105aa6108c9366004614995565b611d83565b3480156108da57600080fd5b5061057d6108e9366004614896565b611de2565b3480156108fa57600080fd5b506105aa610909366004614b56565b611e5c565b34801561091a57600080fd5b5061057d60175481565b34801561093057600080fd5b50601b546104b390610100900460ff1681565b34801561094f57600080fd5b5060175442116104b3565b34801561096657600080fd5b5061057d7f8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef81565b34801561099a57600080fd5b50601554610538906001600160a01b031681565b3480156109ba57600080fd5b506105386109c9366004614896565b611ea7565b3480156109da57600080fd5b5061057d6109e9366004614896565b600f6020526000908152604090205481565b348015610a0757600080fd5b506105aa610a16366004614d83565b611ebe565b348015610a2757600080fd5b506105aa610a36366004614896565b611fc7565b348015610a4757600080fd5b5061057d610a56366004614995565b611fe5565b348015610a6757600080fd5b506105aa61206e565b348015610a7c57600080fd5b506104b3610a8b366004614896565b6000908152600f60205260409020541590565b348015610aaa57600080fd5b506105aa610ab9366004614896565b6120a4565b348015610aca57600080fd5b506105aa610ad9366004614896565b6120c2565b348015610aea57600080fd5b506021546104e9906001600160a01b031681565b348015610b0a57600080fd5b50600d546001600160a01b0316610538565b348015610b2857600080fd5b506105aa610b37366004614896565b6120e0565b348015610b4857600080fd5b506104b3610b573660046148f3565b60009182526013602090815260408084206001600160a01b0393909316845291905290205460ff1690565b348015610b8e57600080fd5b506105aa610b9d3660046148f3565b6120fe565b348015610bae57600080fd5b5061057d610bbd366004614896565b612157565b348015610bce57600080fd5b5061050b6121f1565b348015610be357600080fd5b506022546104e9906001600160a01b031681565b348015610c0357600080fd5b5061057d610c12366004614995565b601e6020526000908152604090205481565b348015610c3057600080fd5b5061057d60195481565b6105aa610c48366004614896565b612200565b348015610c5957600080fd5b5061057d600081565b348015610c6e57600080fd5b506105aa610c7d366004614dcb565b6122fd565b348015610c8e57600080fd5b506105aa612395565b348015610ca357600080fd5b50610cb7610cb2366004614896565b6123f6565b6040516104c09190614ef9565b348015610cd057600080fd5b506105aa610cdf366004614995565b612631565b348015610cf057600080fd5b506105aa610cff366004614f0a565b61266c565b348015610d1057600080fd5b506104b3610d1f366004614995565b600e6020526000908152604090205460ff1681565b348015610d4057600080fd5b5061057d60145481565b348015610d5657600080fd5b5061057d60165481565b348015610d6c57600080fd5b506105aa610d7b366004615012565b612753565b348015610d8c57600080fd5b5061050b610d9b366004614896565b612791565b348015610dac57600080fd5b5061057d610dbb366004614995565b612b37565b348015610dcc57600080fd5b506105aa610ddb366004614d17565b612b69565b6105aa610dee366004615085565b612b95565b348015610dff57600080fd5b506105aa610e0e366004614c3a565b612db8565b348015610e1f57600080fd5b506105aa610e2e3660046148f3565b6130cd565b348015610e3f57600080fd5b5061057d60185481565b348015610e5557600080fd5b506105aa610e64366004614896565b6130f2565b348015610e7557600080fd5b506105aa610e84366004614896565b613110565b348015610e9557600080fd5b506104b3610ea43660046150d5565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610ede57600080fd5b50601f546104e9906001600160a01b031681565b348015610efe57600080fd5b506105aa610f0d366004614995565b61312e565b348015610f1e57600080fd5b506105aa610f2d366004614995565b613169565b348015610f3e57600080fd5b506105aa610f4d366004614c3a565b6131c2565b6000610f5d82613545565b92915050565b606060018054610f729061510d565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9e9061510d565b8015610feb5780601f10610fc057610100808354040283529160200191610feb565b820191906000526020600020905b815481529060010190602001808311610fce57829003601f168201915b5050505050905090565b60006110008261356a565b6110255760405162461bcd60e51b815260040161101c9061515b565b60405180910390fd5b506000908152600560205260409020546001600160a01b031690565b600061104c82611ea7565b9050806001600160a01b0316836001600160a01b031614156110805760405162461bcd60e51b815260040161101c9061518b565b336001600160a01b038216148061109c575061109c8133610ea4565b6110b85760405162461bcd60e51b815260040161101c906151bb565b6110c283836135a1565b505050565b600080516020615dfe8339815191526110df8161360f565b50602180546001600160a01b0319166001600160a01b0392909216919091179055565b600061110c613619565b60045461111991906151e1565b905090565b336001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909161461118b57337f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990960405163073e64fd60e21b815260040161101c9291906151f8565b6111958282613679565b5050565b6000818152600f6020526040902054156111c55760405162461bcd60e51b815260040161101c9061522e565b6110c28383836136c3565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba46111fa8161360f565b6112038261356a565b61121f5760405162461bcd60e51b815260040161101c90615256565b611195826136f4565b6000828152601360205260409020600101546112438161360f565b6110c28383613804565b60008060005b6004548110156112c1576112668161356a565b801561128b575061127681611ea7565b6001600160a01b0316856001600160a01b0316145b156112af57838214156112a1579150610f5d9050565b816112ab81615266565b9250505b806112b981615266565b915050611253565b5060405162461bcd60e51b815260040161101c9061529b565b83336112e582611ea7565b6001600160a01b03161461130c576040516349e27cff60e01b815260040160405180910390fd5b601f54604051627eeac760e11b815283916001600160a01b03169062fdd58e9061133c90339085906004016152ab565b60206040518083038186803b15801561135457600080fd5b505afa158015611368573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061138c91906152d1565b6113a9576040516349e27cff60e01b815260040160405180910390fd5b8285858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050601f5460405163c19a4ef560e01b81526001600160a01b03909116925063c19a4ef59150611410908590600401614936565b60006040518083038186803b15801561142857600080fd5b505afa15801561143c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052611464919081019061534a565b60405160200161147491906153a7565b604051602081830303815290604052805190602001208160405160200161149b91906153a7565b60405160208183030381529060405280519060200120146114cf57604051631e4cbc7f60e21b815260040160405180910390fd5b601f5460405163adc0f74560e01b815286918a916001600160a01b039091169063adc0f74590611503908590600401614936565b60206040518083038186803b15801561151b57600080fd5b505afa15801561152f573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061155391906152d1565b6000828152601d6020526040902060090154101561158457604051636e7e5ecf60e01b815260040160405180910390fd5b600260125414156115a75760405162461bcd60e51b815260040161101c906153e7565b60026012556040516000906115c2908b908b9060200161540a565b60408051601f19818403018152828252805160209182012060008f8152601d835292909220919350909183916115f89101615417565b604051602081830303815290604052805190602001201415611642576004810154156116365760405162461bcd60e51b815260040161101c90615447565b60048101899055611877565b816040516020016116529061546b565b60405160208183030381529060405280519060200120141561169c576003810154156116905760405162461bcd60e51b815260040161101c90615447565b60038101899055611877565b816040516020016116ac90615476565b6040516020818303038152906040528051906020012014156116f6576005810154156116ea5760405162461bcd60e51b815260040161101c90615447565b60058101899055611877565b81604051602001611706906154a6565b604051602081830303815290604052805190602001201415611750576002810154156117445760405162461bcd60e51b815260040161101c90615447565b60028101899055611877565b81604051602001611760906154c8565b6040516020818303038152906040528051906020012014156117aa5760068101541561179e5760405162461bcd60e51b815260040161101c90615447565b60068101899055611877565b816040516020016117ba906154d3565b604051602081830303815290604052805190602001201415611804576007810154156117f85760405162461bcd60e51b815260040161101c90615447565b60078101899055611877565b81604051602001611814906154fc565b60405160208183030381529060405280519060200120141561185e576008810154156118525760405162461bcd60e51b815260040161101c90615447565b60088101899055611877565b604051631e4cbc7f60e21b815260040160405180910390fd5b601f546001600160a01b0316639eef4aa68a6001336040518463ffffffff1660e01b81526004016118aa9392919061551c565b600060405180830381600087803b1580156118c457600080fd5b505af11580156118d8573d6000803e3d6000fd5b505050508b7f913887fd0b468ebff22eac13535c8b5a656d89040bff7d16d7d4531bf27030d68c8c8c60405161191093929190615567565b60405180910390a25050600160125550505050505050505050565b6001600160a01b03811633146119535760405162461bcd60e51b815260040161101c906155e5565b61119582826138a6565b600080516020615dfe8339815191526119758161360f565b6015546040516000916001600160a01b0316904790611993906155f5565b60006040518083038185875af1925050503d80600081146119d0576040519150601f19603f3d011682016040523d82523d6000602084013e6119d5565b606091505b50509050806111955760405162461bcd60e51b815260040161101c9061561a565b8233611a0182611ea7565b6001600160a01b031614611a28576040516349e27cff60e01b815260040160405180910390fd5b8282600082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509394505050505b8151811015611ae3576000828281518110611a8257611a8261562a565b01602001516001600160f81b0319169050601160f91b811480611ab25750601760fa1b6001600160f81b03198216145b15611ad057604051630ec0325960e21b815260040160405180910390fd5b5080611adb81615266565b915050611a65565b50600086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052508c8152601d6020526040908190209051949550611b3f946001909101935091506156ae9050565b604051809103902081805190602001201415611b6e57604051632a9ffab760e21b815260040160405180910390fd5b6000888152601d60205260409020611b8a9060010188886146d0565b50877f1d83c2282d074aad212f8c5d02271066bf42c603a85c4c9e4f07d1eb8c1998218888604051611bbd9291906156ba565b60405180910390a25050505050505050565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba4611bf98161360f565b611c028261356a565b611c1e5760405162461bcd60e51b815260040161101c90615256565b61119582613929565b6110c283838360405180602001604052806000815250612753565b60606000611c4f83611fe5565b905080611c705760408051600080825260208201909252905b509392505050565b60008167ffffffffffffffff811115611c8b57611c8b6149b6565b604051908082528060200260200182016040528015611cb4578160200160208202803683370190505b50905060005b82811015611c6857611ccc858261124d565b828281518110611cde57611cde61562a565b602090810291909101015280611cf381615266565b915050611cba565b600080516020615dfe833981519152611d138161360f565b50601b80549115156101000261ff0019909216919091179055565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba4611d588161360f565b6000838152601d602052604081206009018054849290611d799084906151e1565b9091555050505050565b600080516020615dfe833981519152611d9b8161360f565b600060145411611dbd5760405162461bcd60e51b815260040161101c906156e5565b611dd98260145460405180602001604052806000815250613a96565b50506000601455565b6000611dec611102565b8210611e0a5760405162461bcd60e51b815260040161101c9061529b565b6000805b600454811015611e5557611e218161356a565b15611e435783821415611e35579392505050565b81611e3f81615266565b9250505b80611e4d81615266565b915050611e0e565b5050919050565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba4611e868161360f565b6000838152601d602052604081206009018054849290611d799084906156f5565b6000806000611eb584613ab6565b50949350505050565b60026012541415611ee15760405162461bcd60e51b815260040161101c906153e7565b60026012556017544211611f075760405162461bcd60e51b815260040161101c90615256565b60005b81811015611fa3576020546001600160a01b03166323b872dd3361dead868686818110611f3957611f3961562a565b905060200201356040518463ffffffff1660e01b8152600401611f5e9392919061570d565b600060405180830381600087803b158015611f7857600080fd5b505af1158015611f8c573d6000803e3d6000fd5b505050508080611f9b90615266565b915050611f0a565b50611fbe336040805160208101909152600081528390613a96565b50506001601255565b600080516020615dfe833981519152611fdf8161360f565b50601855565b60006001600160a01b03821661200d5760405162461bcd60e51b815260040161101c90615758565b6000805b600454811015612067576120248161356a565b156120575761203281611ea7565b6001600160a01b0316846001600160a01b031614156120575761205482615266565b91505b61206081615266565b9050612011565b5092915050565b600d546001600160a01b031633146120985760405162461bcd60e51b815260040161101c9061579a565b6120a26000613b08565b565b600080516020615dfe8339815191526120bc8161360f565b50601c55565b600080516020615dfe8339815191526120da8161360f565b50601755565b600080516020615dfe8339815191526120f88161360f565b50601955565b7ff11b02a75234472a5060a94045900fd33989cb6e8ec8dd50e38ed9a49356cba46121288161360f565b6121318361356a565b61214d5760405162461bcd60e51b815260040161101c90615256565b6110c28383613b5a565b60006121628261356a565b61217e5760405162461bcd60e51b815260040161101c9061515b565b60006009600061218d85613ced565b815260200190815260200160002054905080600014156121bf5760405162461bcd60e51b815260040161101c906157cc565b80836040516020016121d29291906157dc565b60408051601f1981840301815291905280516020909101209392505050565b606060028054610f729061510d565b60175442116122215760405162461bcd60e51b815260040161101c90615256565b6018548161222d611102565b61223791906156f5565b106122545760405162461bcd60e51b815260040161101c90615802565b6019546122619082615812565b3410156122805760405162461bcd60e51b815260040161101c90615849565b601a54336000908152601e602052604090205461229e9083906156f5565b106122bb5760405162461bcd60e51b815260040161101c90615871565b336000908152601e6020526040812080548392906122da9084906156f5565b909155506122fa9050338260405180602001604052806000815250613a96565b50565b6001600160a01b0382163314156123265760405162461bcd60e51b815260040161101c906158a0565b3360008181526006602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31906123899085906147b6565b60405180910390a35050565b600080516020615dfe8339815191526123ad8161360f565b6123b5613d37565b7f15120e52505e619cbf6c2af910d5cf7f9ee1befa55801b078c33e93880b2d6096123de611102565b6040516123eb9190614936565b60405180910390a150565b61245c60405180610180016040528060608152602001606081526020016000815260200160008152602001600081526020016000815260200160008152602001600081526020016000815260200160008152602001600015158152602001600081525090565b6124658261356a565b6124815760405162461bcd60e51b815260040161101c90615256565b6000828152601d602052604090819020815161018081019092528054829082906124aa9061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546124d69061510d565b80156125235780601f106124f857610100808354040283529160200191612523565b820191906000526020600020905b81548152906001019060200180831161250657829003601f168201915b5050505050815260200160018201805461253c9061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546125689061510d565b80156125b55780601f1061258a576101008083540402835291602001916125b5565b820191906000526020600020905b81548152906001019060200180831161259857829003601f168201915b505050918352505060028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c0820152600882015460e08201526009820154610100820152600a82015460ff161515610120820152600b909101546101409091015292915050565b600080516020615dfe8339815191526126498161360f565b50601f80546001600160a01b0319166001600160a01b0392909216919091179055565b600d546001600160a01b031633146126965760405162461bcd60e51b815260040161101c9061579a565b8281146126b55760405162461bcd60e51b815260040161101c906158ce565b60005b8381101561274c578282828181106126d2576126d261562a565b90506020020160208101906126e79190614d17565b600e60008787858181106126fd576126fd61562a565b90506020020160208101906127129190614995565b6001600160a01b031681526020810191909152604001600020805460ff19169115159190911790558061274481615266565b9150506126b8565b5050505050565b6000828152600f60205260409020541561277f5760405162461bcd60e51b815260040161101c9061522e565b61278b84848484613ec4565b50505050565b601b54606090610100900460ff1661282757602154604051632914130560e01b81526001600160a01b03909116906329141305906127d3908590600401614936565b60006040518083038186803b1580156127eb57600080fd5b505afa1580156127ff573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610f5d919081019061534a565b6128308261356a565b61284c5760405162461bcd60e51b815260040161101c90615256565b6000828152601d6020526040808220815161018081019092528054829082906128749061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546128a09061510d565b80156128ed5780601f106128c2576101008083540402835291602001916128ed565b820191906000526020600020905b8154815290600101906020018083116128d057829003601f168201915b505050505081526020016001820180546129069061510d565b80601f01602080910402602001604051908101604052809291908181526020018280546129329061510d565b801561297f5780601f106129545761010080835404028352916020019161297f565b820191906000526020600020905b81548152906001019060200180831161296257829003601f168201915b505050918352505060028201546020820152600382015460408201526004820154606082015260058201546080820152600682015460a0820152600782015460c0820152600882015460e08201526009820154610100820152600a82015460ff161515610120820152600b90910154610140909101529050612a0e836000908152600f60205260409020541590565b15156101408201526022546001600160a01b031663de325b8f612a3085611ea7565b6040518263ffffffff1660e01b8152600401612a4c91906148d1565b60206040518083038186803b158015612a6457600080fd5b505afa158015612a78573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612a9c91906152d1565b6101608201526021546001600160a01b031663f3b95d0384612abd81612157565b846040518463ffffffff1660e01b8152600401612adc939291906158de565b60006040518083038186803b158015612af457600080fd5b505afa158015612b08573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052612b30919081019061534a565b9392505050565b6001600160a01b0381166000908152601e6020526040812054601a54600191612b5f916151e1565b610f5d91906151e1565b600080516020615dfe833981519152612b818161360f565b50601b805460ff1916911515919091179055565b60026012541415612bb85760405162461bcd60e51b815260040161101c906153e7565b60026012556016544211612bde5760405162461bcd60e51b815260040161101c90615256565b60185483612bea611102565b612bf491906156f5565b10612c115760405162461bcd60e51b815260040161101c90615802565b601954612c1e9084615812565b341015612c3d5760405162461bcd60e51b815260040161101c90615849565b601a54336000908152601e6020526040902054612c5b9085906156f5565b10612c785760405162461bcd60e51b815260040161101c90615871565b600033604051602001612c8b919061593c565b604051602081830303815290604052805190602001209050612ce483838080602002602001604051908101604052809392919081815260200183836020028082843760009201919091525050601c549150849050613ef6565b612d005760405162461bcd60e51b815260040161101c90615969565b336000908152601e602052604081208054869290612d1f9084906156f5565b90915550612d3f9050338560405180602001604052806000815250613a96565b601b5460ff1615612dad57601f546001600160a01b0316633cbf48e933866040518363ffffffff1660e01b8152600401612d7a9291906152ab565b600060405180830381600087803b158015612d9457600080fd5b505af1158015612da8573d6000803e3d6000fd5b505050505b505060016012555050565b8233612dc382611ea7565b6001600160a01b031614612dea576040516349e27cff60e01b815260040160405180910390fd5b60026012541415612e0d5760405162461bcd60e51b815260040161101c906153e7565b60026012556040516000908190612e2a908690869060200161540a565b60408051601f19818403018152828252805160209182012060008a8152601d83529290922091935090918391612e609101615417565b604051602081830303815290604052805190602001201415612e8e5760048101805460009091559250612ffe565b81604051602001612e9e9061546b565b604051602081830303815290604052805190602001201415612ecc5760038101805460009091559250612ffe565b81604051602001612edc90615476565b604051602081830303815290604052805190602001201415612f0a5760058101805460009091559250612ffe565b81604051602001612f1a906154a6565b604051602081830303815290604052805190602001201415612f485760028101805460009091559250612ffe565b81604051602001612f58906154c8565b604051602081830303815290604052805190602001201415612f865760068101805460009091559250612ffe565b81604051602001612f96906154d3565b604051602081830303815290604052805190602001201415612fc45760078101805460009091559250612ffe565b81604051602001612fd4906154fc565b60405160208183030381529060405280519060200120141561185e57600881018054600090915592505b6000831161301e5760405162461bcd60e51b815260040161101c90615994565b601f546001600160a01b031663466e79eb846001336040518463ffffffff1660e01b81526004016130519392919061551c565b600060405180830381600087803b15801561306b57600080fd5b505af115801561307f573d6000803e3d6000fd5b50505050867fd4596d80f81394606eec2500c28df457c069fe45c83d304190e97e0a8061d6b78787866040516130b793929190615567565b60405180910390a2505060016012555050505050565b6000828152601360205260409020600101546130e88161360f565b6110c283836138a6565b600080516020615dfe83398151915261310a8161360f565b50601655565b600080516020615dfe8339815191526131288161360f565b50601a55565b600080516020615dfe8339815191526131468161360f565b50601580546001600160a01b0319166001600160a01b0392909216919091179055565b600d546001600160a01b031633146131935760405162461bcd60e51b815260040161101c9061579a565b6001600160a01b0381166131b95760405162461bcd60e51b815260040161101c906159e7565b6122fa81613b08565b82336131cd82611ea7565b6001600160a01b0316146131f4576040516349e27cff60e01b815260040160405180910390fd5b8282600082828080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509394505050505b81518110156132af57600082828151811061324e5761324e61562a565b01602001516001600160f81b0319169050601160f91b81148061327e5750601760fa1b6001600160f81b03198216145b1561329c57604051630ec0325960e21b815260040160405180910390fd5b50806132a781615266565b915050613231565b50600086868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050825192935050506019101561330e5760405163251f56a160e21b815260040160405180910390fd5b6000888152601d602052604090819020905161332a91906156ae565b60405180910390208180519060200120141561335957604051632a9ffab760e21b815260040160405180910390fd5b6000888152601d602052604090206133729088886146d0565b50877f8edfa912e70e283a8ef6d6f52cd1faef9690ff989eff2f11a134e8478ba7b28b8888604051611bbd9291906156ba565b600454600881901c60009081526007602052604090208054600160ff1b60ff84161c17905561278b848484613401565b600881901c600090815260209290925260409091208054600160ff1b60ff9093169290921c9091179055565b600454826134215760405162461bcd60e51b815260040161101c90615a12565b6001600160a01b0384166134475760405162461bcd60e51b815260040161101c90615a45565b60005b838110156134d557600061345e82846156f5565b60405190915081906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46134a66000878387613f0c565b6134c25760405162461bcd60e51b815260040161101c90615a89565b50806134cd81615266565b91505061344a565b50600081815260036020908152604080832080546001600160a01b0319166001600160a01b038916179055600884901c83529082905290208054600160ff1b60ff84161c179055826004600082825461352e91906156f5565b9091555061278b9050600085838684565b3b151590565b60006001600160e01b03198216637965db0b60e01b1480610f5d5750610f5d8261401a565b600881901c6000908152600c6020526040812054600160ff1b60ff84161c161561359657506000919050565b610f5d826004541190565b600081815260056020526040902080546001600160a01b0319166001600160a01b03841690811790915581906135d682611ea7565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6122fa8133614085565b6000806008600454901c600161362f91906156f5565b905060005b81811015613674576000818152600c602052604090205461365481614105565b61365e90856156f5565b935050808061366c90615266565b915050613634565b505090565b60008160008151811061368e5761368e61562a565b60209081029190910181015160008581526008835260408082205480835281832083905560099094529020819055915061278b565b6136cd3382614124565b6136e95760405162461bcd60e51b815260040161101c906151bb565b6110c28383836141c5565b336000908152600e602052604090205460ff166137235760405162461bcd60e51b815260040161101c90615acd565b60008181526011602090815260408083203384529091529020541561375a5760405162461bcd60e51b815260040161101c90615b11565b6000818152600f60205260408120546137749060016156f5565b6000838152601060209081526040808320848452825280832080546001600160a01b03191633908117909155868452601183528184209084528252808320849055858352600f90915281208054929350906137ce83615266565b9091555050604051339083907f9ecfd70e9ff36df72989324a49559383d39f9290d700b10cf5ac10dcb68d264390600090a35050565b60008281526013602090815260408083206001600160a01b038516845290915290205460ff166111955760008281526013602090815260408083206001600160a01b03851684529091529020805460ff191660011790556138623390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60008281526013602090815260408083206001600160a01b038516845290915290205460ff16156111955760008281526013602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b336000908152600e602052604090205460ff166139585760405162461bcd60e51b815260040161101c90615acd565b60008181526011602090815260408083203384529091529020548061398f5760405162461bcd60e51b815260040161101c90615b55565b6000828152600f6020526040902054818114613a055760008381526010602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155868452601183528184209084529091529020829055613a2d565b6000838152601060209081526040808320858452909152902080546001600160a01b03191690555b60008381526011602090815260408083203384528252808320839055858352600f9091528120805491613a5f83615b65565b9091555050604051339084907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a3505050565b600454600b546000828152600a602052604090205561278b8484846133a5565b600080613ac28361356a565b613ade5760405162461bcd60e51b815260040161101c9061515b565b613ae78361435a565b6000818152600360205260409020546001600160a01b031694909350915050565b600d80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b0381166000908152600e602052604090205460ff1615613b935760405162461bcd60e51b815260040161101c90615acd565b60008281526011602090815260408083206001600160a01b038516845290915290205480613bd35760405162461bcd60e51b815260040161101c90615bb0565b6000838152600f6020526040902054818114613c495760008481526010602090815260408083208484528252808320805486855282852080546001600160a01b03199081166001600160a01b03909316928317909155825416909155878452601183528184209084529091529020829055613c71565b6000848152601060209081526040808320858452909152902080546001600160a01b03191690555b60008481526011602090815260408083206001600160a01b03871684528252808320839055868352600f9091528120805491613cac83615b65565b90915550506040516001600160a01b0384169085907f0fe7d9801197f79ef3b1595d19379eb58f0fff5f98b0f6d6f34c03cae5306c3790600090a350505050565b6000613cf88261356a565b613d145760405162461bcd60e51b815260040161101c9061515b565b600a6000613d2184614366565b8152602001908152602001600020549050919050565b6040516305d3b1d360e41b81526000907f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699096001600160a01b031690635d3b1d3090613e0f907f8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef907f0000000000000000000000000000000000000000000000000000000000000185907f0000000000000000000000000000000000000000000000000000000000000003907f0000000000000000000000000000000000000000000000000000000000061a8090600190600401615beb565b602060405180830381600087803b158015613e2957600080fd5b505af1158015613e3d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190613e6191906152d1565b90507f76421cb080d40e8a03ba462b500012451ba59bdebc46694dc458807c1d754b6281604051613e929190614936565b60405180910390a1600b54600082815260086020526040902055600b8054906000613ebc83615266565b919050555050565b613ece3383614124565b613eea5760405162461bcd60e51b815260040161101c906151bb565b61278b84848484614373565b600082613f0385846143a6565b14949350505050565b60006001600160a01b0384163b1561400e57604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290613f50903390899088908890600401615c37565b602060405180830381600087803b158015613f6a57600080fd5b505af1925050508015613f9a575060408051601f3d908101601f19168201909252613f9791810190615c7c565b60015b613ff4573d808015613fc8576040519150601f19603f3d011682016040523d82523d6000602084013e613fcd565b606091505b508051613fec5760405162461bcd60e51b815260040161101c90615a89565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050614012565b5060015b949350505050565b60006001600160e01b031982166380ac58cd60e01b148061404b57506001600160e01b03198216635b5e139f60e01b145b8061406657506001600160e01b0319821663780e9d6360e01b145b80610f5d57506301ffc9a760e01b6001600160e01b0319831614610f5d565b60008281526013602090815260408083206001600160a01b038516845290915290205460ff16611195576140c3816001600160a01b03166014614412565b6140ce836020614412565b6040516020016140df929190615c9d565b60408051601f198184030181529082905262461bcd60e51b825261101c91600401614874565b60005b811561411f57600019820190911690600101614108565b919050565b600061412f8261356a565b61414b5760405162461bcd60e51b815260040161101c90615d1e565b600061415683611ea7565b9050806001600160a01b0316846001600160a01b031614806141915750836001600160a01b031661418684610ff5565b6001600160a01b0316145b8061401257506001600160a01b0380821660009081526006602090815260408083209388168352929052205460ff16614012565b6000806141d183613ab6565b91509150846001600160a01b0316826001600160a01b0316146142065760405162461bcd60e51b815260040161101c90615d4b565b6001600160a01b03841661422c5760405162461bcd60e51b815260040161101c90615d7d565b6142376000846135a1565b60006142448460016156f5565b600881901c600090815260208190526040902054909150600160ff1b60ff83161c16158015614274575060045481105b156142c057600081815260036020908152604080832080546001600160a01b0319166001600160a01b038b16179055600884901c83529082905290208054600160ff1b60ff84161c1790555b600084815260036020526040902080546001600160a01b0319166001600160a01b03871617905581841461431157600884901c60009081526020819052604090208054600160ff1b60ff87161c1790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050505050565b6000610f5d818361458b565b6000610f5d60078361458b565b61437e8484846141c5565b61438a84848484613f0c565b61278b5760405162461bcd60e51b815260040161101c90615a89565b600081815b8451811015611c685760008582815181106143c8576143c861562a565b602002602001015190508083116143ee57600083815260208290526040902092506143ff565b600081815260208490526040902092505b508061440a81615266565b9150506143ab565b60606000614421836002615812565b61442c9060026156f5565b67ffffffffffffffff811115614444576144446149b6565b6040519080825280601f01601f19166020018201604052801561446e576020820181803683370190505b509050600360fc1b816000815181106144895761448961562a565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106144b8576144b861562a565b60200101906001600160f81b031916908160001a90535060006144dc846002615812565b6144e79060016156f5565b90505b600181111561456c577f303132333435363738396162636465660000000000000000000000000000000085600f16601081106145285761452861562a565b1a60f81b82828151811061453e5761453e61562a565b60200101906001600160f81b031916908160001a90535060049490941c9361456581615b65565b90506144ea565b508315612b305760405162461bcd60e51b815260040161101c90615dbf565b600881901c60008181526020849052604081205490919060ff8085169190821890811c80156145d3576145bd8161464e565b60ff168303600885901b17945050505050610f5d565b600084116145f35760405162461bcd60e51b815260040161101c9061515b565b6000199093019260ff9250600091505b506000838152602087905260409020548015614622576145bd8161464e565b600084116146425760405162461bcd60e51b815260040161101c90615ded565b60001990930192614603565b60006040518061012001604052806101008152602001615e1e610100913960f87e818283848586878898a8b8c8d8e8f929395969799a9b9d9e9faaeb6bedeeff614697856146b8565b02901c815181106146aa576146aa61562a565b016020015160f81c92915050565b60008082116146c657600080fd5b5060008190031690565b8280546146dc9061510d565b90600052602060002090601f0160209004810192826146fe5760008555614744565b82601f106147175782800160ff19823516178555614744565b82800160010185558215614744579182015b82811115614744578235825591602001919060010190614729565b50614750929150614754565b5090565b5b808211156147505760008155600101614755565b6001600160e01b031981165b81146122fa57600080fd5b8035610f5d81614769565b6000602082840312156147a0576147a0600080fd5b60006140128484614780565b8015155b82525050565b60208101610f5d82846147ac565b6000610f5d6001600160a01b0383166147db565b90565b6001600160a01b031690565b6000610f5d826147c4565b6000610f5d826147e7565b6147b0816147f2565b60208101610f5d82846147fd565b60005b8381101561482f578181015183820152602001614817565b8381111561278b5750506000910152565b600061484a825190565b808452602084019350614861818560208601614814565b601f19601f8201165b9093019392505050565b60208082528101612b308184614840565b80614775565b8035610f5d81614885565b6000602082840312156148ab576148ab600080fd5b6000614012848461488b565b60006001600160a01b038216610f5d565b6147b0816148b7565b60208101610f5d82846148c8565b614775816148b7565b8035610f5d816148df565b6000806040838503121561490957614909600080fd5b6000614915858561488b565b9250506020614926858286016148e8565b9150509250929050565b806147b0565b60208101610f5d8284614930565b6000806040838503121561495a5761495a600080fd5b600061496685856148e8565b92505060206149268582860161488b565b67ffffffffffffffff81166147b0565b60208101610f5d8284614977565b6000602082840312156149aa576149aa600080fd5b600061401284846148e8565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff821117156149f2576149f26149b6565b6040525050565b6000614a0460405190565b905061411f82826149cc565b600067ffffffffffffffff821115614a2a57614a2a6149b6565b5060209081020190565b6000614a47614a4284614a10565b6149f9565b83815290506020808201908402830185811115614a6657614a66600080fd5b835b81811015614a8a5780614a7b888261488b565b84525060209283019201614a68565b5050509392505050565b600082601f830112614aa857614aa8600080fd5b8135614012848260208601614a34565b60008060408385031215614ace57614ace600080fd5b6000614ada858561488b565b925050602083013567ffffffffffffffff811115614afa57614afa600080fd5b61492685828601614a94565b600080600060608486031215614b1e57614b1e600080fd5b6000614b2a86866148e8565b9350506020614b3b868287016148e8565b9250506040614b4c8682870161488b565b9150509250925092565b60008060408385031215614b6c57614b6c600080fd5b6000614966858561488b565b60008083601f840112614b8d57614b8d600080fd5b50813567ffffffffffffffff811115614ba857614ba8600080fd5b602083019150836001820283011115614bc357614bc3600080fd5b9250929050565b60008060008060608587031215614be357614be3600080fd5b6000614bef878761488b565b945050602085013567ffffffffffffffff811115614c0f57614c0f600080fd5b614c1b87828801614b78565b93509350506040614c2e8782880161488b565b91505092959194509250565b600080600060408486031215614c5257614c52600080fd5b6000614c5e868661488b565b935050602084013567ffffffffffffffff811115614c7e57614c7e600080fd5b614c8a86828701614b78565b92509250509250925092565b6000614ca28383614930565b505060200190565b6000614cb4825190565b80845260209384019383018060005b83811015614ce8578151614cd78882614c96565b975060208301925050600101614cc3565b509495945050505050565b60208082528101612b308184614caa565b801515614775565b8035610f5d81614d04565b600060208284031215614d2c57614d2c600080fd5b60006140128484614d0c565b60008083601f840112614d4d57614d4d600080fd5b50813567ffffffffffffffff811115614d6857614d68600080fd5b602083019150836020820283011115614bc357614bc3600080fd5b60008060208385031215614d9957614d99600080fd5b823567ffffffffffffffff811115614db357614db3600080fd5b614dbf85828601614d38565b92509250509250929050565b60008060408385031215614de157614de1600080fd5b6000614ded85856148e8565b925050602061492685828601614d0c565b805161018080845260009190840190614e178282614840565b91505060208301518482036020860152614e318282614840565b9150506040830151614e466040860182614930565b506060830151614e596060860182614930565b506080830151614e6c6080860182614930565b5060a0830151614e7f60a0860182614930565b5060c0830151614e9260c0860182614930565b5060e0830151614ea560e0860182614930565b50610100830151614eba610100860182614930565b50610120830151614ecf610120860182614930565b50610140830151614ee46101408601826147ac565b50610160830151611c68610160860182614930565b60208082528101612b308184614dfe565b60008060008060408587031215614f2357614f23600080fd5b843567ffffffffffffffff811115614f3d57614f3d600080fd5b614f4987828801614d38565b9450945050602085013567ffffffffffffffff811115614f6b57614f6b600080fd5b614f7787828801614d38565b95989497509550505050565b600067ffffffffffffffff821115614f9d57614f9d6149b6565b601f19601f83011660200192915050565b82818337506000910152565b6000614fc8614a4284614f83565b905082815260208101848484011115614fe357614fe3600080fd5b611c68848285614fae565b600082601f83011261500257615002600080fd5b8135614012848260208601614fba565b6000806000806080858703121561502b5761502b600080fd5b600061503787876148e8565b9450506020615048878288016148e8565b93505060406150598782880161488b565b925050606085013567ffffffffffffffff81111561507957615079600080fd5b614c2e87828801614fee565b60008060006040848603121561509d5761509d600080fd5b60006150a9868661488b565b935050602084013567ffffffffffffffff8111156150c9576150c9600080fd5b614c8a86828701614d38565b600080604083850312156150eb576150eb600080fd5b600061491585856148e8565b634e487b7160e01b600052602260045260246000fd5b60028104600182168061512157607f821691505b60208210811415615134576151346150f7565b50919050565b60078152600060208201662165786973747360c81b815291505b5060200190565b60208082528101610f5d8161513a565b600981526000602082016808585c1c1c9bdd985b60ba1b81529150615154565b60208082528101610f5d8161516b565b600981526000602082016808585c1c1c9bdd995960ba1b81529150615154565b60208082528101610f5d8161519b565b634e487b7160e01b600052601160045260246000fd5b6000828210156151f3576151f36151cb565b500390565b6040810161520682856148c8565b612b3060208301846148c8565b60048152600060208201633133333760e01b81529150615154565b60208082528101610f5d81615213565b60018152600060208201600360fc1b81529150615154565b60208082528101610f5d8161523e565b600060001982141561527a5761527a6151cb565b5060010190565b600381526000602082016237b7b160e91b81529150615154565b60208082528101610f5d81615281565b604081016152b982856148c8565b612b306020830184614930565b8051610f5d81614885565b6000602082840312156152e6576152e6600080fd5b600061401284846152c6565b6000615300614a4284614f83565b90508281526020810184848401111561531b5761531b600080fd5b611c68848285614814565b600082601f83011261533a5761533a600080fd5b81516140128482602086016152f2565b60006020828403121561535f5761535f600080fd5b815167ffffffffffffffff81111561537957615379600080fd5b61401284828501615326565b600061538f825190565b61539d818560208601614814565b9290920192915050565b6000612b308284615385565b601f81526000602082017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529150615154565b60208082528101610f5d816153b3565b6000615404838584614fae565b50500190565b60006140128284866153f7565b652ba2a0a827a760d11b8152600060068201610f5d565b60028152600060208201611c9b60f11b81529150615154565b60208082528101610f5d8161542e565b631211505160e21b815260005b5060040190565b6000610f5d82615457565b6420a926a7a960d91b8152600060058201610f5d565b69109050d2d1d493d5539160b21b815260005b50600a0190565b6000610f5d8261548c565b692320a1a2afa0a926a7a960b11b8152600061549f565b6000610f5d826154b1565b6622aca2aba2a0a960c91b8152600060078201610f5d565b634d49534360e01b81526000615464565b6000610f5d826154eb565b6000610f5d6147d88381565b6147b081615507565b6060810161552a8286614930565b6155376020830185615513565b61401260408301846148c8565b818352600060208401935061555a838584614fae565b601f19601f84011661486a565b60408082528101615579818587615544565b90506140126020830184614930565b602f81526000602082017f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636581527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015291505b5060400190565b60208082528101610f5d81615588565b6000610f5d826147d8565b600381526000602082016239393960e81b81529150615154565b60208082528101610f5d81615600565b634e487b7160e01b600052603260045260246000fd5b6000815461564d8161510d565b6001821680156156645760018114615675576156a5565b60ff198316865281860193506156a5565b60008581526020902060005b8381101561569d57815488820152600190910190602001615681565b838801955050505b50505092915050565b6000612b308284615640565b60208082528101614012818486615544565b6002815260006020820161363960f01b81529150615154565b60208082528101610f5d816156cc565b60008219821115615708576157086151cb565b500190565b6060810161571b82866148c8565b61572860208301856148c8565b6140126040830184614930565b600c81526000602082016b7a65726f206164647265737360a01b81529150615154565b60208082528101610f5d81615735565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657291019081526000615154565b60208082528101610f5d81615768565b600b81526000602082016a08599d5b1b199a5b1b195960aa1b81529150615154565b60208082528101610f5d816157aa565b604081016152b98285614930565b60018152600060208201603960f81b81529150615154565b60208082528101610f5d816157ea565b600081600019048311821515161561582c5761582c6151cb565b500290565b60018152600060208201603160f81b81529150615154565b60208082528101610f5d81615831565b60018152600060208201601960f91b81529150615154565b60208082528101610f5d81615859565b600881526000602082016721617070726f766560c01b81529150615154565b60208082528101610f5d81615881565b6007815260006020820166042d8cadccee8d60cb1b81529150615154565b60208082528101610f5d816158b0565b606081016158ec8286614930565b6158f96020830185614930565b818103604083015261590b8184614dfe565b95945050505050565b6000610f5d8260601b90565b6000610f5d82615914565b6147b0615937826148b7565b615920565b6000615948828461592b565b50601401919050565b60018152600060208201600d60fa1b81529150615154565b60208082528101610f5d81615951565b60048152600060208201633639363960e01b81529150615154565b60208082528101610f5d81615979565b602681526000602082017f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206181526564647265737360d01b602082015291506155de565b60208082528101610f5d816159a4565b60048152600060208201637a65726f60e01b81529150615154565b60208082528101610f5d816159f7565b600c81526000602082016b217a65726f6164647265737360a01b81529150615154565b60208082528101610f5d81615a22565b600f81526000602082017f214552433732315265636569766572000000000000000000000000000000000081529150615154565b60208082528101610f5d81615a55565b601181526000602082017f43616e6e6f7420757064617465206d617000000000000000000000000000000081529150615154565b60208082528101610f5d81615a99565b601b81526000602082017f494420616c7265616479206c6f636b65642062792063616c6c6572000000000081529150615154565b60208082528101610f5d81615add565b601781526000602082017f4944206e6f74206c6f636b65642062792063616c6c657200000000000000000081529150615154565b60208082528101610f5d81615b21565b600081615b7457615b746151cb565b506000190190565b600d81526000602082017f4944206e6f74206c6f636b65640000000000000000000000000000000000000081529150615154565b60208082528101610f5d81615b7c565b61ffff81166147b0565b63ffffffff81166147b0565b600061ffff8216610f5d565b6147b081615bd6565b60a08101615bf98288614930565b615c066020830187614977565b615c136040830186615bc0565b615c206060830185615bca565b615c2d6080830184615be2565b9695505050505050565b60808101615c4582876148c8565b615c5260208301866148c8565b615c5f6040830185614930565b8181036060830152615c2d8184614840565b8051610f5d81614769565b600060208284031215615c9157615c91600080fd5b60006140128484615c71565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526017016000615ccf8285615385565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000815260110191506140128284615385565b600681526000602082016508595e1a5cdd60d21b81529150615154565b60208082528101610f5d81615d01565b60068152600060208201653737ba37bbb760d11b81529150615154565b60208082528101610f5d81615d2e565b600b81526000602082016a7a65726f6164647265737360a81b81529150615154565b60208082528101610f5d81615d5b565b60208082527f537472696e67733a20686578206c656e67746820696e73756666696369656e7491019081526000615154565b60208082528101610f5d81615d8d565b60078152600060208201662165786973745360c81b81529150615154565b60208082528101610f5d81615dcf56feb19546dff01e856fb3f010c267a7b1c60363cf8a4664e21cc89c26224620214e0001020903110a19042112290b311a3905412245134d2a550c5d32651b6d3a7506264262237d468514804e8d2b95569d0d495ea533a966b11c886eb93bc176c9071727374353637324837e9b47af86c7155181ad4fd18ed32c9096db57d59ee30e2e4a6a5f92a6be3498aae067ddb2eb1d5989b56fd7baf33ca0c2ee77e5caf7ff0810182028303840444c545c646c7425617c847f8c949c48a4a8b087b8c0c816365272829aaec650acd0d28fdad4e22d6991bd97dfdcea58b4d6f29fede4f6fe0f1f2f3f4b5b6b607b8b93a3a7b7bf357199c5abcfd9e168bcdee9b3f1ecf5fd1e3e5a7a8aa2b670c4ced8bbe8f0f4fc3d79a1c3cde7effb78cce6facbf9f8a26469706673582212200a69d5a5a7edc680d1e1a299af104003cfb32e049d1009510bb21d5ab5ecdf6864736f6c63430008090033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699098af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef00000000000000000000000000000000000000000000000000000000000001850000000000000000000000000e223db582e3fc2c47ba39f67a1e55b7a75f09fd0000000000000000000000005e2454f33c3da3aa30eabc502255f66a6d72adc8000000000000000000000000e9b41d92c64b4b088a6ddf55057f60195b90e09f000000000000000000000000bd24a76f4135f930f5c49f6c30e0e30a61b97537
-----Decoded View---------------
Arg [0] : _vrfV2Coordinator (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [1] : keyHash_ (bytes32): 0x8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [2] : subscriptionId_ (uint64): 389
Arg [3] : _accessPassContract (address): 0x0E223db582e3fc2c47bA39f67A1E55B7a75F09fD
Arg [4] : _factionContract (address): 0x5E2454F33c3da3Aa30EabC502255f66A6d72aDc8
Arg [5] : _renderingContract (address): 0xE9B41D92C64B4b088A6ddF55057F60195b90e09f
Arg [6] : _vendorContract (address): 0xbd24A76F4135F930F5c49f6c30e0E30A61b97537
-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [1] : 8af398995b04c28e9951adb9721ef74c74f93e6a478f39e7e0777be13527e7ef
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000185
Arg [3] : 0000000000000000000000000e223db582e3fc2c47ba39f67a1e55b7a75f09fd
Arg [4] : 0000000000000000000000005e2454f33c3da3aa30eabc502255f66a6d72adc8
Arg [5] : 000000000000000000000000e9b41d92c64b4b088a6ddf55057f60195b90e09f
Arg [6] : 000000000000000000000000bd24a76f4135f930f5c49f6c30e0e30a61b97537
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.