Feature Tip: Add private address tag to any address under My Name Tag !
ERC-721
Overview
Max Total Supply
139 CBTE
Holders
49
Market
Volume (24H)
N/A
Min Price (24H)
N/A
Max Price (24H)
N/A
Other Info
Token Contract
Balance
1 CBTELoading...
Loading
Loading...
Loading
Loading...
Loading
# | Exchange | Pair | Price | 24H Volume | % Volume |
---|
Contract Name:
CoBotsV2
Compiler Version
v0.8.12+commit.f00d7308
Optimization Enabled:
Yes with 2000 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import "@chainlink/contracts/src/v0.8/interfaces/LinkTokenInterface.sol"; import "@chainlink/contracts/src/v0.8/interfaces/VRFCoordinatorV2Interface.sol"; import "@chainlink/contracts/src/v0.8/VRFConsumerBaseV2.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "erc721a/contracts/ERC721A.sol"; import {ICoBotsRendererV2, TokenData} from "../interfaces/ICoBotsRendererV2.sol"; import "./Schedule.sol"; error BatchLimitExceeded(); error WrongPrice(uint256 paidPrice, uint256 expectedPrice); error TotalSupplyExceeded(); error AllocationExceeded(); error ToggleMettaCallerNotOwner(); error ChainlinkSubscriptionNotFound(); error TransferFailed(); error MysteryChallengeSenderDoesNotOwnENS(); error MysteryChallengeValueDoesNotMatch(); error FulfillmentAlreadyFulfilled(); error FulfillRequestForNonExistentContest(); error FulfillRequestWithTokenNotOwnedByWinner(); error FulfillRequestWithTokenOutOfBounds(); error RedeemTokenNotOwner(); error RedeemTokenAlreadyRedeemed(); error NoGiveawayToTrigger(); error InsufficientFunds(); error WithdrawalFailed(); error FailSafeWithdrawalNotEnabled(); error FulfillRequestRedrawn(); error NonexistentRenderer(); contract CoBotsV2 is ERC721A, VRFConsumerBaseV2, Ownable, ReentrancyGuard, Schedule { // Events event RendererContractUpdated(address indexed renderer); event MettaToggled(uint256 indexed tokenId, bool isMetta); event CheckpointDrawn(uint256 indexed requestId, Prize prize); event CheckpointFulfilled( uint256 indexed requestId, Prize prize, Winner winner ); event GiveawayFinished(); event Withdrawal(uint256 amount); event DrawBeforeWithdrawal(); // Data structures /** @dev The prize struct contains the data for one single giveaway prize * @param checkpoint the number of minted bots required to unlock the give * @param amount the amount of the prize to be won * @param isContest flag to indicate if the prize is a contest (meme, twitter, etc) and to be drawn randomly */ struct Prize { uint16 checkpoint; uint72 amount; bool isContest; } /** @dev The mystery challenge is a special giveaway that will not be drawn nor won after founders selection. * It will require to take control of a given ENS name and to send a message to the contract with the address * owning it. * @param ensId the tokenId of the given ENS * @param value the answer to the challenge * @param prizeIndex the index of this prize in the global Prize[] array */ struct MysteryChallenge { uint256 ensId; uint256 value; uint8 prizeIndex; } /** @dev Global parameters for the project. Non-standards uintN types to ensure struct fits in one slot (256 bits). * @param cobotsV1Discount the discount given when redeeming a CoBot V1. This is a percentage of public price * @param mintOutFoundersWithdrawalDelay the delay between mint out and possible failsafe withdrawal from the founders * @param grandPrizeDelay the delay between mint out and the grand prize draw * @param maxCobots the total supply of CoBots * @param contestDuration after this time, all contest will be turned into random draws * @param mintPublicPrice the public price of one single CoBot. */ struct Parameters { uint16 mintOutFoundersWithdrawalDelay; uint16 grandPrizeDelay; uint16 maxCobots; uint24 contestDuration; uint72 mintPublicPrice; uint72 cobotsV1Discount; } // Constants uint8 public constant MINT_FOUNDERS = 3; uint8 public constant MINT_BATCH_LIMIT = 32; Parameters public PARAMETERS; Prize[] public PRIZES; MysteryChallenge private MYSTERY_CHALLENGE; IERC721 public immutable ENS; IERC721Enumerable public immutable COBOTS_V1; address public immutable COBOTS_V1_ADDRESS; //////////////////////////////////////////////////////////////////////// ////////////////////////// Token /////////////////////////////////////// //////////////////////////////////////////////////////////////////////// address public renderingContractAddress; ICoBotsRendererV2 public renderer; uint8[] public coBotsSeeds; mapping(uint256 => bool) public coBotsV1Redeemed; uint256 private _redeemedCount; function setRenderingContractAddress(address _renderingContractAddress) public onlyOwner { renderingContractAddress = _renderingContractAddress; renderer = ICoBotsRendererV2(renderingContractAddress); emit RendererContractUpdated(renderingContractAddress); } constructor( string memory name_, string memory symbol_, address _rendererAddress, address vrfCoordinator, address link, bytes32 keyHash, Parameters memory _parameters, Prize[] memory _prizes, address ens, address cobotsV1, MysteryChallenge memory _mysteryChallenge ) ERC721A(name_, symbol_) VRFConsumerBaseV2(vrfCoordinator) { setRenderingContractAddress(_rendererAddress); COORDINATOR = VRFCoordinatorV2Interface(vrfCoordinator); LINKTOKEN = LinkTokenInterface(link); gasKeyHash = keyHash; PARAMETERS = _parameters; uint256 _prizesLength = _prizes.length; for (uint256 i = 0; i < _prizesLength; ) { PRIZES.push(_prizes[i]); unchecked { ++i; } } ENS = IERC721(ens); COBOTS_V1_ADDRESS = cobotsV1; COBOTS_V1 = IERC721Enumerable(cobotsV1); MYSTERY_CHALLENGE = _mysteryChallenge; } function _mintCoBots(address to, uint256 quantity) internal { if (quantity > MINT_BATCH_LIMIT) revert BatchLimitExceeded(); bytes32 seeds = keccak256( abi.encodePacked( quantity, msg.sender, msg.value, block.timestamp, block.difficulty ) ); for (uint256 i = 0; i < quantity; ) { coBotsSeeds.push(uint8(seeds[i]) << 1); // insure last digit is 0, used for Metta status unchecked { ++i; } } ERC721A._safeMint(to, quantity); if (_currentIndex == PARAMETERS.maxCobots) { mintedOutTimestamp = block.timestamp; } } modifier supplyAvailable(uint256 quantity) { if (_currentIndex + quantity > PARAMETERS.maxCobots) revert TotalSupplyExceeded(); _; } /** * Mints a batch of Co-Bots to the sender. * * @dev The tokenIdsV1 parameter can be empty. The call will revert only if the sender pretends to own some * Co-Bots V1 that they actually don't. However it accepts already redeemed token and just ignore them silently. * This is to make it easier for people using etherscan to copy a bunch of token Ids without having to * manually check if they are redeemed or not. However, it is optimal in terms of gas fees to only give * tokenIds if they can actually be redeemed. * @param quantity The number of COBOTS to mint. * @param tokenIdsV1 A list of V1 Co-Bots token Ids owned by the sender, used to determine the discount. */ function mintPublicSale(uint256 quantity, uint256[] memory tokenIdsV1) external payable whenPublicSaleOpen supplyAvailable(quantity) nonReentrant { uint256 price = PARAMETERS.mintPublicPrice * quantity; uint256 redeemed = 0; uint256 tokenIdsV1Length = tokenIdsV1.length; for (uint256 i = 0; i < tokenIdsV1Length; ) { if (COBOTS_V1.ownerOf(tokenIdsV1[i]) != _msgSender()) revert RedeemTokenNotOwner(); if (!coBotsV1Redeemed[tokenIdsV1[i]] && redeemed < quantity) { coBotsV1Redeemed[tokenIdsV1[i]] = true; redeemed++; price -= PARAMETERS.mintPublicPrice / PARAMETERS.cobotsV1Discount; } unchecked { ++i; } } _redeemedCount += redeemed; if (msg.value != price) revert WrongPrice(price, msg.value); _mintCoBots(_msgSender(), quantity); } function mintFounders(address to, uint256 quantity) external onlyOwner supplyAvailable(quantity) { if (quantity + _currentIndex > MINT_FOUNDERS) revert AllocationExceeded(); _mintCoBots(to, quantity); } /** @notice Return true if the Co-Bot displays metta screen * @param tokenId The Co-Bot token ID */ function isMettaEnabled(uint256 tokenId) external view returns (bool) { return coBotsSeeds[tokenId] & 1 == 1; } function _toggleMetta(uint256 tokenId) internal { if (ERC721A.ownerOf(tokenId) != _msgSender()) revert ToggleMettaCallerNotOwner(); coBotsSeeds[tokenId] = coBotsSeeds[tokenId] ^ 1; } function toggleMetta(uint256[] calldata tokenIds) public nonReentrant { uint256 tokenIdsLength = tokenIds.length; for (uint256 i = 0; i < tokenIdsLength; ) { _toggleMetta(tokenIds[i]); unchecked { ++i; } } } function tokenURI(uint256 _tokenId) public view virtual override returns (string memory) { if (!_exists(_tokenId)) revert URIQueryForNonexistentToken(); if (renderingContractAddress == address(0)) { return ""; } return renderer.tokenURI(_tokenId, coBotsSeeds[_tokenId]); } function tokenData(uint256 _tokenId) public view returns (TokenData memory) { if (!_exists(_tokenId)) revert URIQueryForNonexistentToken(); if (renderingContractAddress == address(0)) { revert NonexistentRenderer(); } return renderer.tokenData(_tokenId, coBotsSeeds[_tokenId]); } function exists(uint256 _tokenId) external view returns (bool) { return _exists(_tokenId); } receive() external payable {} /** @notice At any point in time, founders can withdraw only up to the required balance to insure that the giveaways * will be paid. We take a conservative approach considering that all the remaining discounted bots will be minted * as soon as possible. */ function withdraw() public onlyOwner { // Draw eventual remaining giveaways if (_shouldDraw()) { emit DrawBeforeWithdrawal(); draw(); } // Start with the current contract's balance uint256 balance = address(this).balance; // Correct amount with giveaways that are pending fulfillments, typically previously drawn random fulfillments uint256 requestIdsLength = requestIds.length; for (uint256 i = 0; i < requestIdsLength; ) { if (!fulfillments[requestIds[i]].fulfilled) { balance -= fulfillments[requestIds[i]].prize.amount; } unchecked { ++i; } } // Use the corrected balance as a base possible withdrawn value uint256 value = balance; if (value == 0) revert InsufficientFunds(); // Compute number of remaining discount sales uint256 remainingVoucher = COBOTS_V1.totalSupply() - _redeemedCount; // Initialize the number of already minted bots for checkpoints uint256 previousCheckpoint = _currentIndex; // Loop over locked checkpoint to estimate funds and withdrawal capacities uint256 prizesLength = PRIZES.length; for (uint256 i = requestIds.length; i < prizesLength; ) { // to unlock the next checkpoint, remainingBots bots need to be minted uint256 remainingBots = PRIZES[i].checkpoint - previousCheckpoint; // They will top up the contract's balance, depending on the number of voucher if (remainingVoucher > remainingBots) { balance += remainingBots * (PARAMETERS.mintPublicPrice / PARAMETERS.cobotsV1Discount); remainingVoucher -= remainingBots; } else { balance += remainingVoucher * (PARAMETERS.mintPublicPrice / PARAMETERS.cobotsV1Discount) + (remainingBots - remainingVoucher) * PARAMETERS.mintPublicPrice; remainingVoucher = 0; } // Then the current prize will be paid balance -= PRIZES[i].amount; // If at some point in the future it's not possible to pay, then the withdraw tx is reverted if (balance < 1) { revert InsufficientFunds(); } // The possible withdrawal amount is the minimum between the current balance and the contract's balance // after each giveaway. if (balance < value) { value = balance; } previousCheckpoint = PRIZES[i].checkpoint; unchecked { ++i; } } (bool success, ) = _msgSender().call{value: value}(""); if (!success) revert WithdrawalFailed(); emit Withdrawal(value); } /** @notice A very basic function to act as a failsafe if the contract has a bug somewhere in the fulfill functions. */ function failsafeWithdraw() public onlyOwner whenMintedOut { if ( block.timestamp < (mintedOutTimestamp + PARAMETERS.mintOutFoundersWithdrawalDelay) ) { revert FailSafeWithdrawalNotEnabled(); } uint256 value = address(this).balance; (bool success, ) = _msgSender().call{value: value}(""); if (!success) revert WithdrawalFailed(); emit Withdrawal(value); } //////////////////////////////////////////////////////////////////////// ////////////////////////// Raffle ////////////////////////////////////// //////////////////////////////////////////////////////////////////////// VRFCoordinatorV2Interface public immutable COORDINATOR; LinkTokenInterface public immutable LINKTOKEN; bytes32 public immutable gasKeyHash; uint64 public chainlinkSubscriptionId; function createSubscriptionAndFund(uint96 amount) external nonReentrant { if (chainlinkSubscriptionId == 0) { chainlinkSubscriptionId = COORDINATOR.createSubscription(); COORDINATOR.addConsumer(chainlinkSubscriptionId, address(this)); } LINKTOKEN.transferAndCall( address(COORDINATOR), amount, abi.encode(chainlinkSubscriptionId) ); } function cancelSubscription() external onlyOwner { COORDINATOR.cancelSubscription(chainlinkSubscriptionId, _msgSender()); chainlinkSubscriptionId = 0; } struct Winner { address winner; uint16 tokenId; } struct Fulfillment { Prize prize; bool fulfilled; Winner winner; } mapping(uint256 => Fulfillment) public fulfillments; uint256[] public requestIds; uint256 public drawnAmount; /** @notice Use this to retrieve the ordered list of winners with their corresponding prizes and token Id. * Pending fulfillments are included (no winner drawn yet, probably waiting for Chainlink to fulfill). */ function getOrderedFulfillments() external view returns (Fulfillment[] memory) { Fulfillment[] memory result = new Fulfillment[](requestIds.length); for (uint256 i = 0; i < requestIds.length; i++) { result[i] = fulfillments[requestIds[i]]; } return result; } function _shouldDraw() internal view returns (bool) { if (requestIds.length == PRIZES.length) { return false; } if ( (requestIds.length == PRIZES.length - 1) && (block.timestamp < mintedOutTimestamp + PARAMETERS.grandPrizeDelay) ) { return false; } if (PRIZES[requestIds.length].checkpoint > _currentIndex) return false; return true; } /** @notice This function is a failsafe in case a Chainlink VRF request does not resolve * (behaviour experimented on rinkeby). * The new draws will override the previous ones. */ function redrawPendingFulfillments() public nonReentrant { uint256 requestIdsLength = requestIds.length; for (uint256 i = 0; i < requestIdsLength; ) { if ( !fulfillments[requestIds[i]].fulfilled && (!fulfillments[requestIds[i]].prize.isContest || block.timestamp > publicSaleStartTimestamp + PARAMETERS.contestDuration) ) { uint256 requestId = COORDINATOR.requestRandomWords( gasKeyHash, chainlinkSubscriptionId, 5, // requestConfirmations 500_000, // callbackGasLimit 1 // numWords ); fulfillments[requestId] = Fulfillment( fulfillments[requestIds[i]].prize, false, Winner(address(0), 0) ); delete fulfillments[requestIds[i]]; requestIds[i] = requestId; } unchecked { ++i; } } } /** * @notice This function can be called at any time by anyone to trigger the unlocked giveaways. It will * revert if there is nothing to unlock to prevent anon from making useless tx. (Usually wallet, e.g. * metamask, warn this before signing). * Giveaways that use Chainlink VRF oracle will be fulfilled automatically by Chainlink. Giveaways that * require founders to unlock will be fulfilled by the founders. */ function draw() public nonReentrant { uint256 drawCounts = requestIds.length; if (chainlinkSubscriptionId == 0) { revert ChainlinkSubscriptionNotFound(); } if (!_shouldDraw()) revert NoGiveawayToTrigger(); while (PRIZES[drawCounts].checkpoint < _currentIndex + 1) { uint256 requestId; if ( (PRIZES[drawCounts].isContest && block.timestamp < publicSaleStartTimestamp + PARAMETERS.contestDuration) || (drawCounts == MYSTERY_CHALLENGE.prizeIndex) ) { requestId = _computeRequestId(drawCounts); } else { requestId = COORDINATOR.requestRandomWords( gasKeyHash, chainlinkSubscriptionId, 5, // requestConfirmations 500_000, // callbackGasLimit 1 // numWords ); } drawnAmount += PRIZES[drawCounts].amount; fulfillments[requestId] = Fulfillment( PRIZES[drawCounts], false, Winner(address(0), 0) ); emit CheckpointDrawn(requestId, PRIZES[drawCounts]); drawCounts++; requestIds.push(requestId); if ( (drawCounts == PRIZES.length - 1) && (block.timestamp < mintedOutTimestamp + PARAMETERS.grandPrizeDelay) ) { return; } if (drawCounts == PRIZES.length) { emit GiveawayFinished(); return; } } } function _computeRequestId(uint256 id) private pure returns (uint256) { return uint256(keccak256(abi.encodePacked(uint8(id % type(uint8).max)))); } function _fulfill( uint256 requestId, address winnerAddress, uint256 selectedToken ) internal { if (fulfillments[requestId].fulfilled) { revert FulfillmentAlreadyFulfilled(); } if (fulfillments[requestId].prize.amount == 0) revert FulfillRequestForNonExistentContest(); if (ERC721A.ownerOf(selectedToken) != winnerAddress) { revert FulfillRequestWithTokenNotOwnedByWinner(); } if (selectedToken > fulfillments[requestId].prize.checkpoint - 1) { revert FulfillRequestWithTokenOutOfBounds(); } fulfillments[requestId].fulfilled = true; Winner memory winner = Winner(winnerAddress, uint16(selectedToken)); fulfillments[requestId].winner = winner; (bool success, ) = winnerAddress.call{ value: fulfillments[requestId].prize.amount }(""); if (!success) revert TransferFailed(); emit CheckpointFulfilled( requestId, fulfillments[requestId].prize, winner ); } function fulfillRandomWords(uint256 requestId, uint256[] memory randomWords) internal override { uint256 checkpoint = fulfillments[requestId].prize.checkpoint; if (checkpoint == 0) revert FulfillRequestRedrawn(); uint256 selectedToken = randomWords[0] % checkpoint; address winner = ERC721A.ownerOf(selectedToken); _fulfill(requestId, winner, selectedToken); } /** * @notice This function lets the owner fulfill a giveaway. If the giveaway has not been unlocked, this will * revert. * @param giveawayIndex The index of the giveaway to fulfill, 0 based (the first giveaway is index 0). * @param winner The selected winner address. * @param selectedToken The selected token to be displayed on the website. */ function fulfillContest( uint256 giveawayIndex, address winner, uint256 selectedToken ) external nonReentrant onlyOwner { uint256 requestId = _computeRequestId(giveawayIndex); _fulfill(requestId, winner, selectedToken); } /** * @notice Call this when, you know, you probably know what you're doing here. * revert. * @param value Word biggest mysteries are solved with this single value. * @param tokenId The selected token to be displayed on the website. This should be owned by the winner. */ function TheAnswer(uint256 value, uint256 tokenId) external nonReentrant { if (ENS.ownerOf(MYSTERY_CHALLENGE.ensId) != _msgSender()) { revert MysteryChallengeSenderDoesNotOwnENS(); } if (value != MYSTERY_CHALLENGE.value) { revert MysteryChallengeValueDoesNotMatch(); } _fulfill( _computeRequestId(MYSTERY_CHALLENGE.prizeIndex), _msgSender(), tokenId ); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; interface LinkTokenInterface { function allowance(address owner, address spender) external view returns (uint256 remaining); function approve(address spender, uint256 value) external returns (bool success); function balanceOf(address owner) external view returns (uint256 balance); function decimals() external view returns (uint8 decimalPlaces); function decreaseApproval(address spender, uint256 addedValue) external returns (bool success); function increaseApproval(address spender, uint256 subtractedValue) external; function name() external view returns (string memory tokenName); function symbol() external view returns (string memory tokenSymbol); function totalSupply() external view returns (uint256 totalTokensIssued); function transfer(address to, uint256 value) external returns (bool success); function transferAndCall( address to, uint256 value, bytes calldata data ) external returns (bool success); function transferFrom( address from, address to, uint256 value ) external returns (bool success); }
// 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.0; /** **************************************************************************** * @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 // 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 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 // Creator: Chiru Labs pragma solidity ^0.8.4; 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/Address.sol'; import '@openzeppelin/contracts/utils/Context.sol'; import '@openzeppelin/contracts/utils/Strings.sol'; import '@openzeppelin/contracts/utils/introspection/ERC165.sol'; error ApprovalCallerNotOwnerNorApproved(); error ApprovalQueryForNonexistentToken(); error ApproveToCaller(); error ApprovalToCurrentOwner(); error BalanceQueryForZeroAddress(); error MintedQueryForZeroAddress(); error BurnedQueryForZeroAddress(); error MintToZeroAddress(); error MintZeroQuantity(); error OwnerIndexOutOfBounds(); error OwnerQueryForNonexistentToken(); error TokenIndexOutOfBounds(); error TransferCallerNotOwnerNorApproved(); error TransferFromIncorrectOwner(); error TransferToNonERC721ReceiverImplementer(); error TransferToZeroAddress(); error URIQueryForNonexistentToken(); /** * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including * the Metadata and Enumerable extension. Built to optimize for lower gas during batch mints. * * Assumes serials are sequentially minted starting at 0 (e.g. 0, 1, 2, 3..). * * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply. * * Assumes that the maximum token id cannot exceed 2**128 - 1 (max value of uint128). */ contract ERC721A is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable { using Address for address; using Strings for uint256; // Compiler will pack this into a single 256bit word. struct TokenOwnership { // The address of the owner. address addr; // Keeps track of the start time of ownership with minimal overhead for tokenomics. uint64 startTimestamp; // Whether the token has been burned. bool burned; } // Compiler will pack this into a single 256bit word. struct AddressData { // Realistically, 2**64-1 is more than enough. uint64 balance; // Keeps track of mint count with minimal overhead for tokenomics. uint64 numberMinted; // Keeps track of burn count with minimal overhead for tokenomics. uint64 numberBurned; } // Compiler will pack the following // _currentIndex and _burnCounter into a single 256bit word. // The tokenId of the next token to be minted. uint128 internal _currentIndex; // The number of tokens burned. uint128 internal _burnCounter; // Token name string private _name; // Token symbol string private _symbol; // Mapping from token ID to ownership details // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details. mapping(uint256 => TokenOwnership) internal _ownerships; // Mapping owner address to address data mapping(address => AddressData) private _addressData; // Mapping from token ID to approved address mapping(uint256 => address) private _tokenApprovals; // Mapping from owner to operator approvals mapping(address => mapping(address => bool)) private _operatorApprovals; constructor(string memory name_, string memory symbol_) { _name = name_; _symbol = symbol_; } /** * @dev See {IERC721Enumerable-totalSupply}. */ function totalSupply() public view override returns (uint256) { // Counter underflow is impossible as _burnCounter cannot be incremented // more than _currentIndex times unchecked { return _currentIndex - _burnCounter; } } /** * @dev See {IERC721Enumerable-tokenByIndex}. * This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first. * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case. */ function tokenByIndex(uint256 index) public view override returns (uint256) { uint256 numMintedSoFar = _currentIndex; uint256 tokenIdsIdx; // Counter overflow is impossible as the loop breaks when // uint256 i is equal to another uint256 numMintedSoFar. unchecked { for (uint256 i; i < numMintedSoFar; i++) { TokenOwnership memory ownership = _ownerships[i]; if (!ownership.burned) { if (tokenIdsIdx == index) { return i; } tokenIdsIdx++; } } } revert TokenIndexOutOfBounds(); } /** * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}. * This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first. * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case. */ function tokenOfOwnerByIndex(address owner, uint256 index) public view override returns (uint256) { if (index >= balanceOf(owner)) revert OwnerIndexOutOfBounds(); uint256 numMintedSoFar = _currentIndex; uint256 tokenIdsIdx; address currOwnershipAddr; // Counter overflow is impossible as the loop breaks when // uint256 i is equal to another uint256 numMintedSoFar. unchecked { for (uint256 i; i < numMintedSoFar; i++) { TokenOwnership memory ownership = _ownerships[i]; if (ownership.burned) { continue; } if (ownership.addr != address(0)) { currOwnershipAddr = ownership.addr; } if (currOwnershipAddr == owner) { if (tokenIdsIdx == index) { return i; } tokenIdsIdx++; } } } // Execution should never reach this point. revert(); } /** * @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 override returns (uint256) { if (owner == address(0)) revert BalanceQueryForZeroAddress(); return uint256(_addressData[owner].balance); } function _numberMinted(address owner) internal view returns (uint256) { if (owner == address(0)) revert MintedQueryForZeroAddress(); return uint256(_addressData[owner].numberMinted); } function _numberBurned(address owner) internal view returns (uint256) { if (owner == address(0)) revert BurnedQueryForZeroAddress(); return uint256(_addressData[owner].numberBurned); } /** * Gas spent here starts off proportional to the maximum mint batch size. * It gradually moves to O(1) as tokens get transferred around in the collection over time. */ function ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) { uint256 curr = tokenId; unchecked { if (curr < _currentIndex) { TokenOwnership memory ownership = _ownerships[curr]; if (!ownership.burned) { if (ownership.addr != address(0)) { return ownership; } // Invariant: // There will always be an ownership that has an address and is not burned // before an ownership that does not have an address and is not burned. // Hence, curr will not underflow. while (true) { curr--; ownership = _ownerships[curr]; if (ownership.addr != address(0)) { return ownership; } } } } } revert OwnerQueryForNonexistentToken(); } /** * @dev See {IERC721-ownerOf}. */ function ownerOf(uint256 tokenId) public view override returns (address) { return ownershipOf(tokenId).addr; } /** * @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) { if (!_exists(tokenId)) revert URIQueryForNonexistentToken(); 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 override { address owner = ERC721A.ownerOf(tokenId); if (to == owner) revert ApprovalToCurrentOwner(); if (_msgSender() != owner && !isApprovedForAll(owner, _msgSender())) { revert ApprovalCallerNotOwnerNorApproved(); } _approve(to, tokenId, owner); } /** * @dev See {IERC721-getApproved}. */ function getApproved(uint256 tokenId) public view override returns (address) { if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken(); return _tokenApprovals[tokenId]; } /** * @dev See {IERC721-setApprovalForAll}. */ function setApprovalForAll(address operator, bool approved) public override { if (operator == _msgSender()) revert ApproveToCaller(); _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 { _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 { _transfer(from, to, tokenId); if (!_checkOnERC721Received(from, to, tokenId, _data)) { revert TransferToNonERC721ReceiverImplementer(); } } /** * @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 returns (bool) { return tokenId < _currentIndex && !_ownerships[tokenId].burned; } function _safeMint(address to, uint256 quantity) internal { _safeMint(to, quantity, ''); } /** * @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, bytes memory _data ) internal { _mint(to, quantity, _data, true); } /** * @dev Mints `quantity` tokens and transfers them to `to`. * * Requirements: * * - `to` cannot be the zero address. * - `quantity` must be greater than 0. * * Emits a {Transfer} event. */ function _mint( address to, uint256 quantity, bytes memory _data, bool safe ) internal { uint256 startTokenId = _currentIndex; if (to == address(0)) revert MintToZeroAddress(); if (quantity == 0) revert MintZeroQuantity(); _beforeTokenTransfers(address(0), to, startTokenId, quantity); // Overflows are incredibly unrealistic. // balance or numberMinted overflow if current value of either + quantity > 3.4e38 (2**128) - 1 // updatedIndex overflows if _currentIndex + quantity > 3.4e38 (2**128) - 1 unchecked { _addressData[to].balance += uint64(quantity); _addressData[to].numberMinted += uint64(quantity); _ownerships[startTokenId].addr = to; _ownerships[startTokenId].startTimestamp = uint64(block.timestamp); uint256 updatedIndex = startTokenId; for (uint256 i; i < quantity; i++) { emit Transfer(address(0), to, updatedIndex); if (safe && !_checkOnERC721Received(address(0), to, updatedIndex, _data)) { revert TransferToNonERC721ReceiverImplementer(); } updatedIndex++; } _currentIndex = uint128(updatedIndex); } _afterTokenTransfers(address(0), to, startTokenId, quantity); } /** * @dev Transfers `tokenId` from `from` to `to`. * * 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 ) private { TokenOwnership memory prevOwnership = ownershipOf(tokenId); bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr || isApprovedForAll(prevOwnership.addr, _msgSender()) || getApproved(tokenId) == _msgSender()); if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved(); if (prevOwnership.addr != from) revert TransferFromIncorrectOwner(); if (to == address(0)) revert TransferToZeroAddress(); _beforeTokenTransfers(from, to, tokenId, 1); // Clear approvals from the previous owner _approve(address(0), tokenId, prevOwnership.addr); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**128. unchecked { _addressData[from].balance -= 1; _addressData[to].balance += 1; _ownerships[tokenId].addr = to; _ownerships[tokenId].startTimestamp = uint64(block.timestamp); // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it. // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls. uint256 nextTokenId = tokenId + 1; if (_ownerships[nextTokenId].addr == address(0)) { // This will suffice for checking _exists(nextTokenId), // as a burned slot cannot contain the zero address. if (nextTokenId < _currentIndex) { _ownerships[nextTokenId].addr = prevOwnership.addr; _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp; } } } emit Transfer(from, to, tokenId); _afterTokenTransfers(from, to, tokenId, 1); } /** * @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 { TokenOwnership memory prevOwnership = ownershipOf(tokenId); _beforeTokenTransfers(prevOwnership.addr, address(0), tokenId, 1); // Clear approvals from the previous owner _approve(address(0), tokenId, prevOwnership.addr); // Underflow of the sender's balance is impossible because we check for // ownership above and the recipient's balance can't realistically overflow. // Counter overflow is incredibly unrealistic as tokenId would have to be 2**128. unchecked { _addressData[prevOwnership.addr].balance -= 1; _addressData[prevOwnership.addr].numberBurned += 1; // Keep track of who burned the token, and the timestamp of burning. _ownerships[tokenId].addr = prevOwnership.addr; _ownerships[tokenId].startTimestamp = uint64(block.timestamp); _ownerships[tokenId].burned = true; // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it. // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls. uint256 nextTokenId = tokenId + 1; if (_ownerships[nextTokenId].addr == address(0)) { // This will suffice for checking _exists(nextTokenId), // as a burned slot cannot contain the zero address. if (nextTokenId < _currentIndex) { _ownerships[nextTokenId].addr = prevOwnership.addr; _ownerships[nextTokenId].startTimestamp = prevOwnership.startTimestamp; } } } emit Transfer(prevOwnership.addr, address(0), tokenId); _afterTokenTransfers(prevOwnership.addr, address(0), tokenId, 1); // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times. unchecked { _burnCounter++; } } /** * @dev Approve `to` to operate on `tokenId` * * Emits a {Approval} event. */ function _approve( address to, uint256 tokenId, address owner ) private { _tokenApprovals[tokenId] = to; emit Approval(owner, 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(to).onERC721Received.selector; } catch (bytes memory reason) { if (reason.length == 0) { revert TransferToNonERC721ReceiverImplementer(); } else { assembly { revert(add(32, reason), mload(reason)) } } } } else { return true; } } /** * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting. * And also called before burning one token. * * 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`. * - When `to` is zero, `tokenId` will be burned by `from`. * - `from` and `to` are never both zero. */ 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. * And also called after one token has been burned. * * 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` has been * transferred to `to`. * - When `from` is zero, `tokenId` has been minted for `to`. * - When `to` is zero, `tokenId` has been burned by `from`. * - `from` and `to` are never both zero. */ function _afterTokenTransfers( address from, address to, uint256 startTokenId, uint256 quantity ) internal virtual {} }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; struct Attribute { string trait_type; string value; } struct TokenData { string image; string description; string name; Attribute[] attributes; } interface ICoBotsRendererV2 { function tokenURI(uint256 tokenId, uint8 seed) external view returns (string memory); function tokenData(uint256 tokenId, uint8 seed) external view returns (TokenData memory); }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.12; import "@openzeppelin/contracts/access/Ownable.sol"; error PublicSaleOpen(); error PublicSaleNotOpen(); error TokenMintedOut(); error TokenNotMintedOut(); /** @dev This contract can be used to manage some basic scheduling of a token sale. * To have the isMintedOut() function work, it is required to either update the mintedOutTimestamp * or to override the function (using totalSupply() for instance). */ contract Schedule is Ownable { uint256 public publicSaleStartTimestamp; uint256 public mintedOutTimestamp; function openPublicSale() external onlyOwner whenPublicSaleClosed { publicSaleStartTimestamp = block.timestamp; } function isPublicSaleOpen() public view virtual returns (bool) { return publicSaleStartTimestamp != 0 && block.timestamp > publicSaleStartTimestamp; } modifier whenPublicSaleOpen() { if (!isPublicSaleOpen()) revert PublicSaleNotOpen(); _; } modifier whenPublicSaleClosed() { if (isPublicSaleOpen()) revert PublicSaleOpen(); _; } function isMintedOut() public view virtual returns (bool) { return mintedOutTimestamp > 0; } modifier whenMintedOut() { if (!isMintedOut()) revert TokenNotMintedOut(); _; } modifier whenNotMintedOut() { if (isMintedOut()) revert TokenMintedOut(); _; } }
// 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 (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`, checking first that contract recipients * are aware of the ERC721 protocol to prevent tokens from being forever locked. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be have been allowed to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Transfers `tokenId` token from `from` to `to`. * * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * * Emits a {Transfer} event. */ function transferFrom( address from, address to, uint256 tokenId ) external; /** * @dev Gives permission to `to` to transfer `tokenId` token to another account. * The approval is cleared when the token is transferred. * * Only a single account can be approved at a time, so approving the zero address clears previous approvals. * * Requirements: * * - The caller must own the token or be an approved operator. * - `tokenId` must exist. * * Emits an {Approval} event. */ function approve(address to, uint256 tokenId) external; /** * @dev Returns the account approved for `tokenId` token. * * Requirements: * * - `tokenId` must exist. */ function getApproved(uint256 tokenId) external view returns (address operator); /** * @dev Approve or remove `operator` as an operator for the caller. * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller. * * Requirements: * * - The `operator` cannot be the caller. * * Emits an {ApprovalForAll} event. */ function setApprovalForAll(address operator, bool _approved) external; /** * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`. * * See {setApprovalForAll} */ function isApprovedForAll(address owner, address operator) external view returns (bool); /** * @dev Safely transfers `tokenId` token from `from` to `to`. * * Requirements: * * - `from` cannot be the zero address. * - `to` cannot be the zero address. * - `tokenId` token must exist and be owned by `from`. * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}. * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer. * * Emits a {Transfer} event. */ function safeTransferFrom( address from, address to, uint256 tokenId, bytes calldata data ) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 `IERC721.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 // OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT // 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); }
{ "optimizer": { "enabled": true, "runs": 2000, "details": { "yul": true, "yulDetails": { "stackAllocation": true, "optimizerSteps": "dhfoDgvulfnTUtnIf" } } }, "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":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"},{"internalType":"address","name":"_rendererAddress","type":"address"},{"internalType":"address","name":"vrfCoordinator","type":"address"},{"internalType":"address","name":"link","type":"address"},{"internalType":"bytes32","name":"keyHash","type":"bytes32"},{"components":[{"internalType":"uint16","name":"mintOutFoundersWithdrawalDelay","type":"uint16"},{"internalType":"uint16","name":"grandPrizeDelay","type":"uint16"},{"internalType":"uint16","name":"maxCobots","type":"uint16"},{"internalType":"uint24","name":"contestDuration","type":"uint24"},{"internalType":"uint72","name":"mintPublicPrice","type":"uint72"},{"internalType":"uint72","name":"cobotsV1Discount","type":"uint72"}],"internalType":"struct CoBotsV2.Parameters","name":"_parameters","type":"tuple"},{"components":[{"internalType":"uint16","name":"checkpoint","type":"uint16"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"bool","name":"isContest","type":"bool"}],"internalType":"struct CoBotsV2.Prize[]","name":"_prizes","type":"tuple[]"},{"internalType":"address","name":"ens","type":"address"},{"internalType":"address","name":"cobotsV1","type":"address"},{"components":[{"internalType":"uint256","name":"ensId","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint8","name":"prizeIndex","type":"uint8"}],"internalType":"struct CoBotsV2.MysteryChallenge","name":"_mysteryChallenge","type":"tuple"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AllocationExceeded","type":"error"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"BatchLimitExceeded","type":"error"},{"inputs":[],"name":"ChainlinkSubscriptionNotFound","type":"error"},{"inputs":[],"name":"FailSafeWithdrawalNotEnabled","type":"error"},{"inputs":[],"name":"FulfillRequestForNonExistentContest","type":"error"},{"inputs":[],"name":"FulfillRequestRedrawn","type":"error"},{"inputs":[],"name":"FulfillRequestWithTokenNotOwnedByWinner","type":"error"},{"inputs":[],"name":"FulfillRequestWithTokenOutOfBounds","type":"error"},{"inputs":[],"name":"FulfillmentAlreadyFulfilled","type":"error"},{"inputs":[],"name":"InsufficientFunds","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"MysteryChallengeSenderDoesNotOwnENS","type":"error"},{"inputs":[],"name":"MysteryChallengeValueDoesNotMatch","type":"error"},{"inputs":[],"name":"NoGiveawayToTrigger","type":"error"},{"inputs":[],"name":"NonexistentRenderer","type":"error"},{"inputs":[{"internalType":"address","name":"have","type":"address"},{"internalType":"address","name":"want","type":"address"}],"name":"OnlyCoordinatorCanFulfill","type":"error"},{"inputs":[],"name":"OwnerIndexOutOfBounds","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"PublicSaleNotOpen","type":"error"},{"inputs":[],"name":"PublicSaleOpen","type":"error"},{"inputs":[],"name":"RedeemTokenNotOwner","type":"error"},{"inputs":[],"name":"ToggleMettaCallerNotOwner","type":"error"},{"inputs":[],"name":"TokenIndexOutOfBounds","type":"error"},{"inputs":[],"name":"TokenNotMintedOut","type":"error"},{"inputs":[],"name":"TotalSupplyExceeded","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFailed","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"WithdrawalFailed","type":"error"},{"inputs":[{"internalType":"uint256","name":"paidPrice","type":"uint256"},{"internalType":"uint256","name":"expectedPrice","type":"uint256"}],"name":"WrongPrice","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":"requestId","type":"uint256"},{"components":[{"internalType":"uint16","name":"checkpoint","type":"uint16"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"bool","name":"isContest","type":"bool"}],"indexed":false,"internalType":"struct CoBotsV2.Prize","name":"prize","type":"tuple"}],"name":"CheckpointDrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"requestId","type":"uint256"},{"components":[{"internalType":"uint16","name":"checkpoint","type":"uint16"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"bool","name":"isContest","type":"bool"}],"indexed":false,"internalType":"struct CoBotsV2.Prize","name":"prize","type":"tuple"},{"components":[{"internalType":"address","name":"winner","type":"address"},{"internalType":"uint16","name":"tokenId","type":"uint16"}],"indexed":false,"internalType":"struct CoBotsV2.Winner","name":"winner","type":"tuple"}],"name":"CheckpointFulfilled","type":"event"},{"anonymous":false,"inputs":[],"name":"DrawBeforeWithdrawal","type":"event"},{"anonymous":false,"inputs":[],"name":"GiveawayFinished","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bool","name":"isMetta","type":"bool"}],"name":"MettaToggled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"renderer","type":"address"}],"name":"RendererContractUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdrawal","type":"event"},{"inputs":[],"name":"COBOTS_V1","outputs":[{"internalType":"contract IERC721Enumerable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COBOTS_V1_ADDRESS","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COORDINATOR","outputs":[{"internalType":"contract VRFCoordinatorV2Interface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ENS","outputs":[{"internalType":"contract IERC721","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"LINKTOKEN","outputs":[{"internalType":"contract LinkTokenInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_BATCH_LIMIT","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_FOUNDERS","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PARAMETERS","outputs":[{"internalType":"uint16","name":"mintOutFoundersWithdrawalDelay","type":"uint16"},{"internalType":"uint16","name":"grandPrizeDelay","type":"uint16"},{"internalType":"uint16","name":"maxCobots","type":"uint16"},{"internalType":"uint24","name":"contestDuration","type":"uint24"},{"internalType":"uint72","name":"mintPublicPrice","type":"uint72"},{"internalType":"uint72","name":"cobotsV1Discount","type":"uint72"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"PRIZES","outputs":[{"internalType":"uint16","name":"checkpoint","type":"uint16"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"bool","name":"isContest","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"TheAnswer","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cancelSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"chainlinkSubscriptionId","outputs":[{"internalType":"uint64","name":"","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"coBotsSeeds","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"coBotsV1Redeemed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint96","name":"amount","type":"uint96"}],"name":"createSubscriptionAndFund","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"draw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"drawnAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"failsafeWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"giveawayIndex","type":"uint256"},{"internalType":"address","name":"winner","type":"address"},{"internalType":"uint256","name":"selectedToken","type":"uint256"}],"name":"fulfillContest","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"fulfillments","outputs":[{"components":[{"internalType":"uint16","name":"checkpoint","type":"uint16"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"bool","name":"isContest","type":"bool"}],"internalType":"struct CoBotsV2.Prize","name":"prize","type":"tuple"},{"internalType":"bool","name":"fulfilled","type":"bool"},{"components":[{"internalType":"address","name":"winner","type":"address"},{"internalType":"uint16","name":"tokenId","type":"uint16"}],"internalType":"struct CoBotsV2.Winner","name":"winner","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gasKeyHash","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getOrderedFulfillments","outputs":[{"components":[{"components":[{"internalType":"uint16","name":"checkpoint","type":"uint16"},{"internalType":"uint72","name":"amount","type":"uint72"},{"internalType":"bool","name":"isContest","type":"bool"}],"internalType":"struct CoBotsV2.Prize","name":"prize","type":"tuple"},{"internalType":"bool","name":"fulfilled","type":"bool"},{"components":[{"internalType":"address","name":"winner","type":"address"},{"internalType":"uint16","name":"tokenId","type":"uint16"}],"internalType":"struct CoBotsV2.Winner","name":"winner","type":"tuple"}],"internalType":"struct CoBotsV2.Fulfillment[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isMettaEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintedOut","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isPublicSaleOpen","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mintFounders","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"uint256[]","name":"tokenIdsV1","type":"uint256[]"}],"name":"mintPublicSale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintedOutTimestamp","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openPublicSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleStartTimestamp","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":"redrawPendingFulfillments","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renderer","outputs":[{"internalType":"contract ICoBotsRendererV2","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renderingContractAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requestIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_renderingContractAddress","type":"address"}],"name":"setRenderingContractAddress","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":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"toggleMetta","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":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenData","outputs":[{"components":[{"internalType":"string","name":"image","type":"string"},{"internalType":"string","name":"description","type":"string"},{"internalType":"string","name":"name","type":"string"},{"components":[{"internalType":"string","name":"trait_type","type":"string"},{"internalType":"string","name":"value","type":"string"}],"internalType":"struct Attribute[]","name":"attributes","type":"tuple[]"}],"internalType":"struct TokenData","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]
Contract Creation Code
6101606040523480156200001257600080fd5b5060405162005d0238038062005d028339810160408190526200003591620007e6565b878b8b81600190805190602001906200005092919062000331565b5080516200006690600290602084019062000331565b5050506001600160a01b0316608052620000803362000253565b60016008556200009089620002a5565b6001600160a01b03808916610100528716610120526101408690528451600b80546020880151604089015160608a015160808b015160a08c01516001600160481b03908116600160901b02600160901b600160d81b03199190921669010000000000000000000216600160481b600160d81b031962ffffff90931666010000000000000262ffffff60301b1961ffff958616640100000000021664ffffffffff60201b19968616620100000263ffffffff199098169590991694909417959095179390931695909517179390931617919091179055835160005b818110156200020657600c8682815181106200018a576200018a62000947565b6020908102919091018101518254600181810185556000948552938390208251910180549383015160409093015115156b0100000000000000000000000260ff60581b196001600160481b0390941662010000026001600160581b031990951661ffff909316929092179390931791909116179055016200016a565b50506001600160a01b0392831660a052911660e081905260c0528051600d556020810151600e5560400151600f805460ff191660ff90921691909117905550620009df9650505050505050565b600780546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6007546001600160a01b03163314620002db5760405162461bcd60e51b8152600401620002d2906200095d565b60405180910390fd5b601080546001600160a01b0383166001600160a01b0319918216811790925560118054909116821790556040517f2926c01a1380ae82a404a8c554ad486a6842a4a320d80b770e2930d763825e4f90600090a250565b8280546200033f90620009ae565b90600052602060002090601f016020900481019282620003635760008555620003ae565b82601f106200037e57805160ff1916838001178555620003ae565b82800160010185558215620003ae579182015b82811115620003ae57825182559160200191906001019062000391565b50620003bc929150620003c0565b5090565b5b80821115620003bc5760008155600101620003c1565b634e487b7160e01b600052604160045260246000fd5b601f19601f83011681016001600160401b0381118282101715620004155762000415620003d7565b6040525050565b60006200042860405190565b9050620004368282620003ed565b919050565b60006001600160401b03821115620004575762000457620003d7565b601f19601f83011660200192915050565b60005b83811015620004855781810151838201526020016200046b565b8381111562000495576000848401525b50505050565b6000620004b2620004ac846200043b565b6200041c565b905082815260208101848484011115620004cf57620004cf600080fd5b620004dc84828562000468565b509392505050565b600082601f830112620004fa57620004fa600080fd5b81516200050c8482602086016200049b565b949350505050565b60006001600160a01b0382165b92915050565b620005328162000514565b81146200053e57600080fd5b50565b8051620005218162000527565b8062000532565b805162000521816200054e565b61ffff811662000532565b8051620005218162000562565b62ffffff811662000532565b805162000521816200057a565b6001600160481b03811662000532565b8051620005218162000593565b600060c08284031215620005c757620005c7600080fd5b620005d360c06200041c565b90506000620005e384846200056d565b908201526020620005f7848483016200056d565b9082015260406200060b848483016200056d565b9082015260606200061f8484830162000586565b9082015260806200063384848301620005a3565b9082015260a06200064784848301620005a3565b9082015292915050565b60006001600160401b038211156200066d576200066d620003d7565b5060209081020190565b80151562000532565b8051620005218162000677565b600060608284031215620006a457620006a4600080fd5b620006b060606200041c565b90506000620006c084846200056d565b908201526020620006d484848301620005a3565b908201526040620006478484830162000680565b6000620006f9620004ac8462000651565b838152905060208101606084028301858111156200071a576200071a600080fd5b835b8181101562000742576200073187826200068d565b83526020909201916060016200071c565b5050509392505050565b600082601f830112620007625762000762600080fd5b81516200050c848260208601620006e8565b60ff811662000532565b8051620005218162000774565b600060608284031215620007a257620007a2600080fd5b620007ae60606200041c565b90506000620007be848462000555565b908201526020620007d28484830162000555565b90820152604062000647848483016200077e565b60008060008060008060008060008060006102408c8e0312156200080d576200080d600080fd5b8b516001600160401b03811115620008285762000828600080fd5b620008368e828f01620004e4565b60208e0151909c5090506001600160401b03811115620008595762000859600080fd5b620008678e828f01620004e4565b9a505060406200087a8e828f0162000541565b99505060606200088d8e828f0162000541565b9850506080620008a08e828f0162000541565b97505060a0620008b38e828f0162000555565b96505060c0620008c68e828f01620005b0565b6101808e015190965090506001600160401b03811115620008ea57620008ea600080fd5b620008f88e828f016200074c565b9450506101a06200090c8e828f0162000541565b9350506101c0620009208e828f0162000541565b9250506101e0620009348e828f016200078b565b9150509295989b509295989b9093969950565b634e487b7160e01b600052603260045260246000fd5b60208082528181019081527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260408301526060820162000521565b634e487b7160e01b600052602260045260246000fd5b600281046001821680620009c357607f821691505b60208210811415620009d957620009d962000998565b50919050565b60805160a05160c05160e05161010051610120516101405161526d62000a9560003960008181610c680152818161125701526123ac0152600081816107860152612d8201526000818161069d0152818161122a0152818161191b0152818161237f01528181612c3601528181612d010152612dab01526000610b64015260008181610c3401528181611c050152612fbf0152600081816105550152610f680152600081816116bb01526116e3015261526d6000f3fe6080604052600436106103905760003560e01c80635a08cae5116101dc578063a9b5898f11610102578063d7822c99116100a0578063e985e9c51161006f578063e985e9c514610bb9578063f2fde38b14610c02578063fef490f314610c22578063ffae2b5614610c5657600080fd5b8063d7822c9914610b3c578063dce6c25914610b52578063dfc7e2c914610b86578063e10a64dd14610ba657600080fd5b8063b88d4fde116100dc578063b88d4fde14610abc578063c074f41214610adc578063c87b56dd14610afc578063cf62c8ab14610b1c57600080fd5b8063a9b5898f146109f6578063b4b5b48f14610a7a578063b585209b14610aa757600080fd5b806386758e711161017a57806395d89b411161014957806395d89b41146109895780639a14f79d1461099e578063a22cb465146109b4578063a715b15b146109d457600080fd5b806386758e711461090b5780638796ba8c1461092b5780638ada6b0f1461094b5780638da5cb5b1461096b57600080fd5b806370a08231116101b657806370a0823114610891578063715018a6146108b157806372c64f16146108c657806381870fd1146108f657600080fd5b80635a08cae5146107a85780636352211e1461085a57806368d99f7c1461087a57600080fd5b80631fd9d081116102c15780633b2bcbf11161025f5780634e02099f1161022e5780634e02099f146107145780634f558e79146107345780634f6ccce71461075457806355380dfb1461077457600080fd5b80633b2bcbf11461068b5780633ccfd60b146106bf57806342842e0e146106d457806349cae612146106f457600080fd5b806321e182081161029b57806321e182081461062157806323b872dd1461063657806324e9edb0146106565780632f745c591461066b57600080fd5b80631fd9d081146105a45780631fe543e3146105d357806320c5780c146105f357600080fd5b80630f8236081161032e57806318160ddd1161030857806318160ddd146104f25780631a6949e31461052e5780631d2e2cc4146105435780631fafadbc1461058457600080fd5b80630f8236081461049b57806312b40a9f146104bd578063143a3f92146104dd57600080fd5b8063081812fc1161036a578063081812fc14610417578063095ea7b3146104445780630badbd07146104665780630eecae211461048657600080fd5b806301ffc9a71461039c57806304035a92146103d257806306fdde03146103f557600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506103bc6103b7366004614054565b610c8a565b6040516103c9919061407f565b60405180910390f35b3480156103de57600080fd5b506103e8600a5481565b6040516103c99190614093565b34801561040157600080fd5b5061040a610d5b565b6040516103c991906140ff565b34801561042357600080fd5b50610437610432366004614128565b610ded565b6040516103c99190614163565b34801561045057600080fd5b5061046461045f366004614185565b610e4a565b005b34801561047257600080fd5b506104646104813660046141c2565b610f0a565b34801561049257600080fd5b50610464611082565b3480156104a757600080fd5b506104b0600381565b6040516103c991906141ed565b3480156104c957600080fd5b506104646104d83660046141fb565b61158a565b3480156104e957600080fd5b506104b0602081565b3480156104fe57600080fd5b506103e86000546001600160801b0370010000000000000000000000000000000082048116918116919091031690565b34801561053a57600080fd5b506103bc611617565b34801561054f57600080fd5b506105777f000000000000000000000000000000000000000000000000000000000000000081565b6040516103c9919061425e565b34801561059057600080fd5b506104b061059f366004614128565b611632565b3480156105b057600080fd5b506105c46105bf366004614128565b611666565b6040516103c993929190614287565b3480156105df57600080fd5b506104646105ee3660046143b4565b6116b0565b3480156105ff57600080fd5b506015546106149067ffffffffffffffff1681565b6040516103c99190614412565b34801561062d57600080fd5b50610464611744565b34801561064257600080fd5b50610464610651366004614420565b6118b3565b34801561066257600080fd5b506104646118be565b34801561067757600080fd5b506103e8610686366004614185565b6119a0565b34801561069757600080fd5b506105777f000000000000000000000000000000000000000000000000000000000000000081565b3480156106cb57600080fd5b50610464611ab6565b3480156106e057600080fd5b506104646106ef366004614420565b611f69565b34801561070057600080fd5b5061046461070f366004614470565b611f84565b34801561072057600080fd5b5061046461072f366004614185565b611ff9565b34801561074057600080fd5b506103bc61074f366004614128565b6120df565b34801561076057600080fd5b506103e861076f366004614128565b6120ea565b34801561078057600080fd5b506105777f000000000000000000000000000000000000000000000000000000000000000081565b3480156107b457600080fd5b5061084b6107c3366004614128565b6016602090815260009182526040918290208251606081018452815461ffff808216835268ffffffffffffffffff620100008304168386015260ff6b0100000000000000000000009092048216151583870152600184015486518088019097526002909401546001600160a01b0381168752600160a01b900416938501939093529291169083565b6040516103c9939291906144e5565b34801561086657600080fd5b50610437610875366004614128565b6121ae565b34801561088657600080fd5b50600a5415156103bc565b34801561089d57600080fd5b506103e86108ac3660046141fb565b6121c0565b3480156108bd57600080fd5b50610464612228565b3480156108d257600080fd5b506103bc6108e1366004614128565b60136020526000908152604090205460ff1681565b34801561090257600080fd5b5061046461225e565b34801561091757600080fd5b506103bc610926366004614128565b612636565b34801561093757600080fd5b506103e8610946366004614128565b612673565b34801561095757600080fd5b50601154610577906001600160a01b031681565b34801561097757600080fd5b506007546001600160a01b0316610437565b34801561099557600080fd5b5061040a612694565b3480156109aa57600080fd5b506103e860185481565b3480156109c057600080fd5b506104646109cf366004614520565b6126a3565b3480156109e057600080fd5b506109e9612755565b6040516103c991906145e3565b348015610a0257600080fd5b50600b54610a689061ffff808216916201000081048216916401000000008204169062ffffff66010000000000008204169068ffffffffffffffffff69010000000000000000008204811691720100000000000000000000000000000000000090041686565b6040516103c9969594939291906145ff565b348015610a8657600080fd5b50610a9a610a95366004614128565b6128e7565b6040516103c9919061476a565b348015610ab357600080fd5b50610464612a40565b348015610ac857600080fd5b50610464610ad7366004614812565b612aaf565b348015610ae857600080fd5b50601054610437906001600160a01b031681565b348015610b0857600080fd5b5061040a610b17366004614128565b612ae9565b348015610b2857600080fd5b50610464610b373660046148b0565b612bfb565b348015610b4857600080fd5b506103e860095481565b348015610b5e57600080fd5b506104377f000000000000000000000000000000000000000000000000000000000000000081565b348015610b9257600080fd5b50610464610ba1366004614923565b612e54565b610464610bb43660046143b4565b612eb1565b348015610bc557600080fd5b506103bc610bd436600461496b565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610c0e57600080fd5b50610464610c1d3660046141fb565b613205565b348015610c2e57600080fd5b506105777f000000000000000000000000000000000000000000000000000000000000000081565b348015610c6257600080fd5b506103e87f000000000000000000000000000000000000000000000000000000000000000081565b60006001600160e01b031982167f80ac58cd000000000000000000000000000000000000000000000000000000001480610ced57506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610d2157506001600160e01b031982167f780e9d6300000000000000000000000000000000000000000000000000000000145b80610d5557507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b606060018054610d6a906149b4565b80601f0160208091040260200160405190810160405280929190818152602001828054610d96906149b4565b8015610de35780601f10610db857610100808354040283529160200191610de3565b820191906000526020600020905b815481529060010190602001808311610dc657829003601f168201915b5050505050905090565b6000610df882613261565b610e2e576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600560205260409020546001600160a01b031690565b6000610e55826121ae565b9050806001600160a01b0316836001600160a01b03161415610ea3576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614801590610ec35750610ec18133610bd4565b155b15610efa576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f05838383613295565b505050565b60026008541415610f365760405162461bcd60e51b8152600401610f2d90614a0d565b60405180910390fd5b6002600855600d546040517f6352211e00000000000000000000000000000000000000000000000000000000815233917f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691636352211e91610fa391600401614093565b602060405180830381865afa158015610fc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe49190614a28565b6001600160a01b031614611024576040517fb2c6179c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54821461105f576040517f8f6d9d6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f54611079906110729060ff166132fe565b3383613339565b50506001600855565b600260085414156110a55760405162461bcd60e51b8152600401610f2d90614a0d565b600260085560175460155467ffffffffffffffff166110f0576040517f15cd15ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110f86135f9565b61112e576040517fc3a7d74d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054611145906001600160801b03166001614a5f565b6001600160801b0316600c828154811061116157611161614a97565b60009182526020909120015461ffff161015611581576000600c828154811061118c5761118c614a97565b6000918252602090912001546b010000000000000000000000900460ff1680156111d35750600b546009546111d0916601000000000000900462ffffff1690614aad565b42105b806111e25750600f5460ff1682145b156111f7576111f0826132fe565b90506112dd565b6015546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691635d3b1d3091611297917f00000000000000000000000000000000000000000000000000000000000000009167ffffffffffffffff909116906005906207a12090600190600401614aee565b6020604051808303816000875af11580156112b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112da9190614b45565b90505b600c82815481106112f0576112f0614a97565b6000918252602082200154601880546201000090920468ffffffffffffffffff1692909161131f908490614aad565b925050819055506040518060600160405280600c848154811061134457611344614a97565b6000918252602080832060408051606081018252939091015461ffff80821685526201000080830468ffffffffffffffffff908116878701526b0100000000000000000000009384900460ff161515878601529588528785018790528351808501855287815280860188905297840197909752888652601684529482902087518051825482870151928601519189166affffffffffffffffffffff199091161791909616909702969096176bff00000000000000000000001916931515029290921784558481015160018501805460ff191691151591909117905593015180516002909301805491909401516001600160a01b0390931675ffffffffffffffffffffffffffffffffffffffffffff1990911617600160a01b9290911691909102179055600c805482917fb40531e03f8d4be5f5bb24f4d1811140fbead25a449a04cdb8e941384a810702918590811061149f5761149f614a97565b906000526020600020016040516114b69190614be8565b60405180910390a2816114c881614bf6565b60178054600181810183556000929092527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c1501849055600c5491945061150f925090614c11565b821480156115355750600b54600a546115329162010000900461ffff1690614aad565b42105b15611541575050611583565b600c5482141561157b576040517fc4f545db975f34de8f12b4353fa42dd295e802239df19ebbe5fd3c245dad0a5a90600090a15050611583565b5061112e565b505b6001600855565b6007546001600160a01b031633146115b45760405162461bcd60e51b8152600401610f2d90614c5c565b601080546001600160a01b03831673ffffffffffffffffffffffffffffffffffffffff19918216811790925560118054909116821790556040517f2926c01a1380ae82a404a8c554ad486a6842a4a320d80b770e2930d763825e4f90600090a250565b600060095460001415801561162d575060095442115b905090565b6012818154811061164257600080fd5b9060005260206000209060209182820401919006915054906101000a900460ff1681565b600c818154811061167657600080fd5b60009182526020909120015461ffff8116915062010000810468ffffffffffffffffff16906b010000000000000000000000900460ff1683565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461173657337f00000000000000000000000000000000000000000000000000000000000000006040517f1cf993f4000000000000000000000000000000000000000000000000000000008152600401610f2d929190614c6c565b6117408282613699565b5050565b6007546001600160a01b0316331461176e5760405162461bcd60e51b8152600401610f2d90614c5c565b600a546117a7576040517fe5b93aca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b54600a546117bb9161ffff1690614aad565b4210156117f4576040517f3e8e963c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040514790600090339083908381818185875af1925050503d8060008114611838576040519150601f19603f3d011682016040523d82523d6000602084013e61183d565b606091505b5050905080611878576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4e70a604b23a8edee2b1d0a656e9b9c00b73ad8bb1afc2c59381ee9f69197de7826040516118a79190614093565b60405180910390a15050565b610f0583838361372c565b6007546001600160a01b031633146118e85760405162461bcd60e51b8152600401610f2d90614c5c565b6015546040517fd7ae1d300000000000000000000000000000000000000000000000000000000081526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169163d7ae1d309161195b9167ffffffffffffffff16903390600401614c87565b600060405180830381600087803b15801561197557600080fd5b505af1158015611989573d6000803e3d6000fd5b50506015805467ffffffffffffffff191690555050565b60006119ab836121c0565b82106119e3576040517f0ddac30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160801b03169080805b83811015611ab057600081815260036020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff161580159282019290925290611a5c5750611aa8565b80516001600160a01b031615611a7157805192505b876001600160a01b0316836001600160a01b03161415611aa65786841415611a9f57509350610d5592505050565b6001909301925b505b6001016119f4565b50600080fd5b6007546001600160a01b03163314611ae05760405162461bcd60e51b8152600401610f2d90614c5c565b611ae86135f9565b15611b1e576040517fa8ad87cbcccddb5ba11ee5851b9075d95af2c88adb9ad0ae9a4f40b810b74cb590600090a1611b1e611082565b601754479060005b81811015611bc5576016600060178381548110611b4557611b45614a97565b6000918252602080832090910154835282019290925260400190206001015460ff16611bbd576016600060178381548110611b8257611b82614a97565b60009182526020808320909101548352820192909252604001902054611bba9068ffffffffffffffffff620100009091041684614c11565b92505b600101611b26565b508180611bfe576040517f356680b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006014547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c859190614b45565b611c8f9190614c11565b600054600c546017549293506001600160801b03909116915b81811015611ea657600083600c8381548110611cc657611cc6614a97565b600091825260209091200154611ce0919061ffff16614c11565b905080851115611d5957600b54611d279068ffffffffffffffffff720100000000000000000000000000000000000082048116916901000000000000000000900416614cab565b611d3c9068ffffffffffffffffff1682614cce565b611d469089614aad565b9750611d528186614c11565b9450611df5565b600b546901000000000000000000900468ffffffffffffffffff16611d7e8683614c11565b611d889190614cce565b600b54611dc59068ffffffffffffffffff720100000000000000000000000000000000000082048116916901000000000000000000900416614cab565b611dda9068ffffffffffffffffff1687614cce565b611de49190614aad565b611dee9089614aad565b9750600094505b600c8281548110611e0857611e08614a97565b600091825260209091200154611e2f9062010000900468ffffffffffffffffff1689614c11565b97506001881015611e6c576040517f356680b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85881015611e78578795505b600c8281548110611e8b57611e8b614a97565b60009182526020909120015461ffff16935050600101611ca8565b50604051600090339086908381818185875af1925050503d8060008114611ee9576040519150601f19603f3d011682016040523d82523d6000602084013e611eee565b606091505b5050905080611f29576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4e70a604b23a8edee2b1d0a656e9b9c00b73ad8bb1afc2c59381ee9f69197de785604051611f589190614093565b60405180910390a150505050505050565b610f0583838360405180602001604052806000815250612aaf565b60026008541415611fa75760405162461bcd60e51b8152600401610f2d90614a0d565b60026008556007546001600160a01b03163314611fd65760405162461bcd60e51b8152600401610f2d90614c5c565b6000611fe1846132fe565b9050611fee818484613339565b505060016008555050565b6007546001600160a01b031633146120235760405162461bcd60e51b8152600401610f2d90614c5c565b600b546000548291640100000000900461ffff169061204c9083906001600160801b0316614aad565b1115612084576040517ffd59427a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005460039061209d906001600160801b031684614aad565b11156120d5576040517f74a5d1f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f058383613994565b6000610d5582613261565b600080546001600160801b031681805b8281101561217b57600081815260036020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff16151591810182905290612172578583141561216b5750949350505050565b6001909201915b506001016120fa565b506040517fa723001c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121b982613a9b565b5192915050565b60006001600160a01b038216612202576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526004602052604090205467ffffffffffffffff1690565b6007546001600160a01b031633146122525760405162461bcd60e51b8152600401610f2d90614c5c565b61225c6000613bd8565b565b600260085414156122815760405162461bcd60e51b8152600401610f2d90614a0d565b600260085560175460005b818110156110795760166000601783815481106122ab576122ab614a97565b6000918252602080832090910154835282019290925260400190206001015460ff16158015612344575060166000601783815481106122ec576122ec614a97565b6000918252602080832090910154835282019290925260400190205460ff6b0100000000000000000000009091041615806123445750600b54600954612341916601000000000000900462ffffff1690614aad565b42115b1561262e576015546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526000916001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691635d3b1d30916123ea917f00000000000000000000000000000000000000000000000000000000000000009167ffffffffffffffff16906005906207a12090600190600401614aee565b6020604051808303816000875af1158015612409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242d9190614b45565b90506040518060600160405280601660006017868154811061245157612451614a97565b600091825260208083209190910154835282810193909352604091820181208251606081018452905461ffff80821683526201000080830468ffffffffffffffffff908116858901526b0100000000000000000000009384900460ff1615158588015293885287870185905285518087018752858152808801869052978601979097528884526016808752858520895180518254828b0151928a01519186166affffffffffffffffffffff199091161791909616909902989098176bff000000000000000000000019169315159092029290921786558685015160018701805460ff1916911515919091179055959092015180516002909501805491909401516001600160a01b0390951675ffffffffffffffffffffffffffffffffffffffffffff1990911617600160a01b9490921693909302179055601780548590811061259c5761259c614a97565b60009182526020808320909101548352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101805460ff19169055600201805475ffffffffffffffffffffffffffffffffffffffffffff19169055601780548291908490811061262057612620614a97565b600091825260209091200155505b60010161228c565b60006012828154811061264b5761264b614a97565b6000918252602091829020918104909101546001601f9092166101000a900481161492915050565b6017818154811061268357600080fd5b600091825260209091200154905081565b606060028054610d6a906149b4565b6001600160a01b0382163314156126e6576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360008181526006602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319061274990859061407f565b60405180910390a35050565b60175460609060009067ffffffffffffffff811115612776576127766142af565b6040519080825280602002602001820160405280156127e657816020015b6040805160c0810182526000606082018181526080830182905260a083018290528252602080830182905283518085018552828152808201929092529282015282526000199092019101816127945790505b50905060005b6017548110156128e157601660006017838154811061280d5761280d614a97565b600091825260208083209091015483528281019390935260409182019020815160c081018352815461ffff8082166060840190815268ffffffffffffffffff62010000840416608085015260ff6b0100000000000000000000009093048316151560a085015283526001840154909116151582860152835180850185526002909301546001600160a01b0381168452600160a01b900416938201939093529082015282518390839081106128c3576128c3614a97565b602002602001018190525080806128d990614bf6565b9150506127ec565b50919050565b6129126040518060800160405280606081526020016060815260200160608152602001606081525090565b61291b82613261565b612951576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546001600160a01b0316612993576040517f38bdd72700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601154601280546001600160a01b03909216916344ec3631918591829081106129be576129be614a97565b90600052602060002090602091828204019190069054906101000a900460ff166040518363ffffffff1660e01b81526004016129fb929190614ced565b600060405180830381865afa158015612a18573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d559190810190614f4e565b6007546001600160a01b03163314612a6a5760405162461bcd60e51b8152600401610f2d90614c5c565b612a72611617565b15612aa9576040517fd205ec1b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b42600955565b612aba84848461372c565b612ac684848484613c37565b612ae3576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060612af482613261565b612b2a576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546001600160a01b0316612b4e57505060408051602081019091526000815290565b601154601280546001600160a01b0390921691635cc518ba91859182908110612b7957612b79614a97565b90600052602060002090602091828204019190069054906101000a900460ff166040518363ffffffff1660e01b8152600401612bb6929190614ced565b600060405180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d559190810190614f89565b60026008541415612c1e5760405162461bcd60e51b8152600401610f2d90614a0d565b600260085560155467ffffffffffffffff16612d72577f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612c94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb89190614fdf565b6015805467ffffffffffffffff191667ffffffffffffffff9290921691821790556040517f7341c10c0000000000000000000000000000000000000000000000000000000081527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031691637341c10c91612d3f91903090600401614c87565b600060405180830381600087803b158015612d5957600080fd5b505af1158015612d6d573d6000803e3d6000fd5b505050505b6015546040516001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001691634000aea0917f0000000000000000000000000000000000000000000000000000000000000000918591612de49167ffffffffffffffff1690602001614412565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612e1193929190615023565b6020604051808303816000875af1158015612e30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611079919061505b565b60026008541415612e775760405162461bcd60e51b8152600401610f2d90614a0d565b60026008558060005b81811015611fee57612ea9848483818110612e9d57612e9d614a97565b90506020020135613d69565b600101612e80565b612eb9611617565b612eef576040517f63a2de0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b546000548391640100000000900461ffff1690612f189083906001600160801b0316614aad565b1115612f50576040517ffd59427a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026008541415612f735760405162461bcd60e51b8152600401610f2d90614a0d565b6002600855600b54600090612fa19085906901000000000000000000900468ffffffffffffffffff16614cce565b8351909150600090815b8181101561319957336001600160a01b03167f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316636352211e888481518110612ffe57612ffe614a97565b60200260200101516040518263ffffffff1660e01b81526004016130229190614093565b602060405180830381865afa15801561303f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130639190614a28565b6001600160a01b0316146130a3576040517f5246352300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601360008783815181106130b9576130b9614a97565b60209081029190910181015182528101919091526040016000205460ff161580156130e357508683105b156131915760016013600088848151811061310057613100614a97565b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550828061313890614bf6565b600b54909450613179915068ffffffffffffffffff720100000000000000000000000000000000000082048116916901000000000000000000900416614cab565b61318e9068ffffffffffffffffff1685614c11565b93505b600101612fab565b5081601460008282546131ac9190614aad565b90915550503483146131ee5782346040517f6871963e000000000000000000000000000000000000000000000000000000008152600401610f2d92919061507c565b6131f83387613994565b5050600160085550505050565b6007546001600160a01b0316331461322f5760405162461bcd60e51b8152600401610f2d90614c5c565b6001600160a01b0381166132555760405162461bcd60e51b8152600401610f2d90615097565b61325e81613bd8565b50565b600080546001600160801b031682108015610d55575050600090815260036020526040902054600160e01b900460ff161590565b600082815260056020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061330b60ff836150f8565b60405160200161331b9190615124565b60408051601f19818403018152919052805160209091012092915050565b60008381526016602052604090206001015460ff1615613385576040517f636d49d300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526016602052604090205462010000900468ffffffffffffffffff166133db576040517f8e1773d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816001600160a01b03166133ee826121ae565b6001600160a01b03161461342e576040517f03e21ec200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526016602052604090205461344d9060019061ffff16615136565b61ffff1681111561348a576040517f518af55d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526016602081815260408084206001818101805460ff19169091179055815180830183526001600160a01b0380891680835261ffff808a168488019081528c8a529790965282516002850180549851909716600160a01b0275ffffffffffffffffffffffffffffffffffffffffffff19909816921691909117959095179093555490519193929168ffffffffffffffffff62010000909204919091169060006040518083038185875af1925050503d8060008114613568576040519150601f19603f3d011682016040523d82523d6000602084013e61356d565b606091505b50509050806135a8576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008581526016602052604090819020905186917f7d2db4ed55b360e8ea7d70390d6f63a1404136410fa6f3f94a41d1cf99488a7f916135ea91908690615144565b60405180910390a25050505050565b600c54601754600091141561360e5750600090565b600c5461361d90600190614c11565b6017541480156136455750600b54600a546136429162010000900461ffff1690614aad565b42105b156136505750600090565b600054601754600c80546001600160801b0390931692909190811061367757613677614a97565b60009182526020909120015461ffff1611156136935750600090565b50600190565b60008281526016602052604090205461ffff16806136e3576040517f018bd28900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081836000815181106136f9576136f9614a97565b602002602001015161370b91906150f8565b90506000613718826121ae565b9050613725858284613339565b5050505050565b600061373782613a9b565b80519091506000906001600160a01b0316336001600160a01b03161480613765575081516137659033610bd4565b8061378057503361377584610ded565b6001600160a01b0316145b9050806137b9576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846001600160a01b031682600001516001600160a01b031614613808576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038416613848576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6138586000848460000151613295565b6001600160a01b038581166000908152600460209081526040808320805467ffffffffffffffff1980821667ffffffffffffffff92831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600390945282852080546001600160e01b031916909417600160a01b42909216919091021790925590860180835291205490911661394d576000546001600160801b031681101561394d578251600082815260036020908152604090912080549186015167ffffffffffffffff16600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613725565b60208111156139cf576040517f359fd04400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081333442446040516020016139ea959493929190615187565b60405160208183030381529060405280519060200120905060005b82811015613a635760126001838360208110613a2357613a23614a97565b83546001808201865560009586526020958690209582049095018054601f9092166101000a60ff818102199093169490931a90941b160217905501613a05565b50613a6e8383613e29565b600b5460005464010000000090910461ffff166001600160801b039091161415610f055742600a55505050565b60408051606081018252600080825260208201819052918101829052905482906001600160801b0316811015613ba657600081815260036020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff16151591810182905290613ba45780516001600160a01b031615613b3a579392505050565b5060001901600081815260036020908152604091829020825160608101845290546001600160a01b038116808352600160a01b820467ffffffffffffffff1693830193909352600160e01b900460ff1615159281019290925215613b9f579392505050565b613b3a565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b15613d5d576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a0290613c949033908990889088906004016151d1565b6020604051808303816000875af1925050508015613ccf575060408051601f3d908101601f19168201909252613ccc91810190615216565b60015b613d2a573d808015613cfd576040519150601f19603f3d011682016040523d82523d6000602084013e613d02565b606091505b508051613d22576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b0319167f150b7a0200000000000000000000000000000000000000000000000000000000149050613d61565b5060015b949350505050565b33613d73826121ae565b6001600160a01b031614613db3576040517fff68d35d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60128181548110613dc657613dc6614a97565b90600052602060002090602091828204019190069054906101000a900460ff1660011860128281548110613dfc57613dfc614a97565b90600052602060002090602091828204019190066101000a81548160ff021916908360ff16021790555050565b611740828260405180602001604052806000815250610f0583838360016000546001600160801b03166001600160a01b038516613e92576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83613ec9576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516600081815260046020908152604080832080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000811667ffffffffffffffff8083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c018116909202179091558584526003909252822080546001600160e01b031916909317600160a01b42909216919091021790915581905b85811015613ff45760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4838015613fca5750613fc86000888488613c37565b155b15613fe8576040516368d2bf6b60e11b815260040160405180910390fd5b60019182019101613f73565b50600080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166001600160801b0392909216919091179055613725565b6001600160e01b031981165b811461325e57600080fd5b8035610d5581614032565b60006020828403121561406957614069600080fd5b6000613d618484614049565b8015155b82525050565b60208101610d558284614075565b80614079565b60208101610d55828461408d565b60005b838110156140bc5781810151838201526020016140a4565b83811115612ae35750506000910152565b60006140d7825190565b8084526020840193506140ee8185602086016140a1565b601f01601f19169290920192915050565b6020808252810161411081846140cd565b9392505050565b8061403e565b8035610d5581614117565b60006020828403121561413d5761413d600080fd5b6000613d61848461411d565b60006001600160a01b038216610d55565b61407981614149565b60208101610d55828461415a565b61403e81614149565b8035610d5581614171565b6000806040838503121561419b5761419b600080fd5b60006141a7858561417a565b92505060206141b88582860161411d565b9150509250929050565b600080604083850312156141d8576141d8600080fd5b60006141a7858561411d565b60ff8116614079565b60208101610d5582846141e4565b60006020828403121561421057614210600080fd5b6000613d61848461417a565b6000610d556001600160a01b038316614233565b90565b6001600160a01b031690565b6000610d558261421c565b6000610d558261423f565b6140798161424a565b60208101610d558284614255565b61ffff8116614079565b68ffffffffffffffffff8116614079565b60608101614295828661426c565b6142a26020830185614276565b613d616040830184614075565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff821117156142eb576142eb6142af565b6040525050565b60006142fd60405190565b905061430982826142c5565b919050565b600067ffffffffffffffff821115614328576143286142af565b5060209081020190565b60006143456143408461430e565b6142f2565b8381529050602080820190840283018581111561436457614364600080fd5b835b8181101561438657614378878261411d565b835260209283019201614366565b5050509392505050565b600082601f8301126143a4576143a4600080fd5b8135613d61848260208601614332565b600080604083850312156143ca576143ca600080fd5b60006143d6858561411d565b925050602083013567ffffffffffffffff8111156143f6576143f6600080fd5b6141b885828601614390565b67ffffffffffffffff8116614079565b60208101610d558284614402565b60008060006060848603121561443857614438600080fd5b6000614444868661417a565b93505060206144558682870161417a565b92505060406144668682870161411d565b9150509250925092565b60008060006060848603121561448857614488600080fd5b6000614444868661411d565b80516144a0838261426c565b5060208101516144b36020840182614276565b506040810151610f056040840182614075565b80516144d2838261415a565b506020810151610f05602084018261426c565b60c081016144f38286614494565b6145006060830185614075565b613d6160808301846144c6565b80151561403e565b8035610d558161450d565b6000806040838503121561453657614536600080fd5b6000614542858561417a565b92505060206141b885828601614515565b805161455f8382614494565b5060208101516145726060840182614075565b506040810151610f0560808401826144c6565b61458f8282614553565b5060c00190565b60200190565b60006145a6825190565b808452602093840193830160005b828110156145d95781516145c88782614585565b9650506020820191506001016145b4565b5093949350505050565b60208082528101614110818461459c565b62ffffff8116614079565b60c0810161460d828961426c565b61461a602083018861426c565b614627604083018761426c565b61463460608301866145f4565b6146416080830185614276565b61464e60a0830184614276565b979650505050505050565b805160408084526000919084019061467182826140cd565b9150506020830151848203602086015261468b82826140cd565b95945050505050565b60006141108383614659565b60006146aa825190565b808452602084019350836020820285016146c48560200190565b60005b848110156146f857838303885281516146e08482614694565b935050602082016020989098019791506001016146c7565b50909695505050505050565b805160808084526000919084019061471c82826140cd565b9150506020830151848203602086015261473682826140cd565b9150506040830151848203604086015261475082826140cd565b9150506060830151848203606086015261468b82826146a0565b602080825281016141108184614704565b600067ffffffffffffffff821115614795576147956142af565b601f19601f83011660200192915050565b82818337506000910152565b60006147c06143408461477b565b9050828152602081018484840111156147db576147db600080fd5b6147e68482856147a6565b509392505050565b600082601f83011261480257614802600080fd5b8135613d618482602086016147b2565b6000806000806080858703121561482b5761482b600080fd5b6000614837878761417a565b94505060206148488782880161417a565b93505060406148598782880161411d565b925050606085013567ffffffffffffffff81111561487957614879600080fd5b614885878288016147ee565b91505092959194509250565b6bffffffffffffffffffffffff811661403e565b8035610d5581614891565b6000602082840312156148c5576148c5600080fd5b6000613d6184846148a5565b60008083601f8401126148e6576148e6600080fd5b50813567ffffffffffffffff81111561490157614901600080fd5b60208301915083602082028301111561491c5761491c600080fd5b9250929050565b6000806020838503121561493957614939600080fd5b823567ffffffffffffffff81111561495357614953600080fd5b61495f858286016148d1565b92509250509250929050565b6000806040838503121561498157614981600080fd5b600061498d858561417a565b92505060206141b88582860161417a565b634e487b7160e01b600052602260045260246000fd5b6002810460018216806149c857607f821691505b602082108114156128e1576128e161499e565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529050614596565b60208082528101610d55816149db565b8051610d5581614171565b600060208284031215614a3d57614a3d600080fd5b6000613d618484614a1d565b634e487b7160e01b600052601160045260246000fd5b6001600160801b03811690506001600160801b03821691506000826001600160801b0303821115614a9257614a92614a49565b500190565b634e487b7160e01b600052603260045260246000fd5b60008219821115614a9257614a92614a49565b6000610d55825b61ffff1690565b61407981614ac0565b600063ffffffff8216610d55565b61407981614ad7565b60a08101614afc828861408d565b614b096020830187614402565b614b166040830186614ace565b614b236060830185614ae5565b614b306080830184614ae5565b9695505050505050565b8051610d5581614117565b600060208284031215614b5a57614b5a600080fd5b6000613d618484614b3a565b6000610d5582614ac7565b6000610d55614b808360101c90565b68ffffffffffffffffff1690565b6000610d55614b9d8360581c90565b60ff1690565b8054614bae81614b66565b614bb8848261426c565b50614bc281614b71565b614bcf6020850182614276565b50614bd981614b8e565b9050610f056040840182614075565b60608101610d558284614ba3565b6000600019821415614c0a57614c0a614a49565b5060010190565b815b9150600082821015614c2757614c27614a49565b500390565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65729101908152614596565b60208082528101610d5581614c2c565b60408101614c7a828561415a565b614110602083018461415a565b60408101614c7a8285614402565b634e487b7160e01b600052601260045260246000fd5b68ffffffffffffffffff9182169116600082614cc957614cc9614c95565b500490565b6000816000190483118215151615614ce857614ce8614a49565b500290565b60408101614cfb828561408d565b61411060208301846141e4565b6000614d166143408461477b565b905082815260208101848484011115614d3157614d31600080fd5b6147e68482856140a1565b600082601f830112614d5057614d50600080fd5b8151613d61848260208601614d08565b600060408284031215614d7557614d75600080fd5b614d7f60406142f2565b825190915067ffffffffffffffff811115614d9c57614d9c600080fd5b614da884828501614d3c565b825250602082015167ffffffffffffffff811115614dc857614dc8600080fd5b614dd484828501614d3c565b60208301525092915050565b6000614dee6143408461430e565b83815290506020808201908402830185811115614e0d57614e0d600080fd5b835b8181101561438657805167ffffffffffffffff811115614e3157614e31600080fd5b8501614e3d8882614d60565b84525060209283019201614e0f565b600082601f830112614e6057614e60600080fd5b8151613d61848260208601614de0565b600060808284031215614e8557614e85600080fd5b614e8f60806142f2565b825190915067ffffffffffffffff811115614eac57614eac600080fd5b614eb884828501614d3c565b825250602082015167ffffffffffffffff811115614ed857614ed8600080fd5b614ee484828501614d3c565b602083015250604082015167ffffffffffffffff811115614f0757614f07600080fd5b614f1384828501614d3c565b604083015250606082015167ffffffffffffffff811115614f3657614f36600080fd5b614f4284828501614e4c565b60608301525092915050565b600060208284031215614f6357614f63600080fd5b815167ffffffffffffffff811115614f7d57614f7d600080fd5b613d6184828501614e70565b600060208284031215614f9e57614f9e600080fd5b815167ffffffffffffffff811115614fb857614fb8600080fd5b613d6184828501614d3c565b67ffffffffffffffff811661403e565b8051610d5581614fc4565b600060208284031215614ff457614ff4600080fd5b6000613d618484614fd4565b6000610d556142306bffffffffffffffffffffffff841681565b61407981615000565b60608101615031828661415a565b61503e602083018561501a565b818103604083015261468b81846140cd565b8051610d558161450d565b60006020828403121561507057615070600080fd5b6000613d618484615050565b6040810161508a828561408d565b614110602083018461408d565b60208082528101610d5581602681527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160208201527f6464726573730000000000000000000000000000000000000000000000000000604082015260600190565b60008261510757615107614c95565b500690565b6000610d558260f81b90565b61407960ff821661510c565b61512e8183615118565b600101919050565b61ffff908116908216614c13565b60a081016151528285614ba3565b61411060608301846144c6565b6000610d558260601b90565b6000610d558261515f565b61407961518282614149565b61516b565b615191818761408d565b60200161519e8186615176565b6014016151ab818561408d565b6020016151b8818461408d565b6020016151c5818361408d565b60200195945050505050565b608081016151df828761415a565b6151ec602083018661415a565b6151f9604083018561408d565b8181036060830152614b3081846140cd565b8051610d5581614032565b60006020828403121561522b5761522b600080fd5b6000613d61848461520b56fea26469706673582212207dd66c8d317298ce56e6a7158ceeab1e7aba2a50e9aee48f85e7c4089ad87e4864736f6c634300080c00330000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000028000000000000000000000000004af8975918169ae48b25da78d5145bd673b2b6e000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded868050000000000000000000000000000000000000000000000000000000000001c200000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000024ea0000000000000000000000000000000000000000000000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000002c000000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea850000000000000000000000002efa2743b863f3bd6f624ac0d58445bc5fb62bf66f4b4baf771f79ee3db2afdf13c35c213ea9f36f199efb86410649ffdf1adb0e000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000b436f2d426f747320322e3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044342544500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c00000000000000000000000000000000000000000000000029a2241af62c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000003782dace9d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000053444835ec580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000006124fee993bc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005dc0000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000007ce66c50e284000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000a688906bd8b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000c249fdd32778000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001770000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b58000000000000000000000000000000000000000000000000f9ccd8a1c508000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002328000000000000000000000000000000000000000000000001314fb37062980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000014d1120d7b160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000003bd913e6c1df400000000000000000000000000000000000000000000000000000000000000000000
Deployed Bytecode
0x6080604052600436106103905760003560e01c80635a08cae5116101dc578063a9b5898f11610102578063d7822c99116100a0578063e985e9c51161006f578063e985e9c514610bb9578063f2fde38b14610c02578063fef490f314610c22578063ffae2b5614610c5657600080fd5b8063d7822c9914610b3c578063dce6c25914610b52578063dfc7e2c914610b86578063e10a64dd14610ba657600080fd5b8063b88d4fde116100dc578063b88d4fde14610abc578063c074f41214610adc578063c87b56dd14610afc578063cf62c8ab14610b1c57600080fd5b8063a9b5898f146109f6578063b4b5b48f14610a7a578063b585209b14610aa757600080fd5b806386758e711161017a57806395d89b411161014957806395d89b41146109895780639a14f79d1461099e578063a22cb465146109b4578063a715b15b146109d457600080fd5b806386758e711461090b5780638796ba8c1461092b5780638ada6b0f1461094b5780638da5cb5b1461096b57600080fd5b806370a08231116101b657806370a0823114610891578063715018a6146108b157806372c64f16146108c657806381870fd1146108f657600080fd5b80635a08cae5146107a85780636352211e1461085a57806368d99f7c1461087a57600080fd5b80631fd9d081116102c15780633b2bcbf11161025f5780634e02099f1161022e5780634e02099f146107145780634f558e79146107345780634f6ccce71461075457806355380dfb1461077457600080fd5b80633b2bcbf11461068b5780633ccfd60b146106bf57806342842e0e146106d457806349cae612146106f457600080fd5b806321e182081161029b57806321e182081461062157806323b872dd1461063657806324e9edb0146106565780632f745c591461066b57600080fd5b80631fd9d081146105a45780631fe543e3146105d357806320c5780c146105f357600080fd5b80630f8236081161032e57806318160ddd1161030857806318160ddd146104f25780631a6949e31461052e5780631d2e2cc4146105435780631fafadbc1461058457600080fd5b80630f8236081461049b57806312b40a9f146104bd578063143a3f92146104dd57600080fd5b8063081812fc1161036a578063081812fc14610417578063095ea7b3146104445780630badbd07146104665780630eecae211461048657600080fd5b806301ffc9a71461039c57806304035a92146103d257806306fdde03146103f557600080fd5b3661039757005b600080fd5b3480156103a857600080fd5b506103bc6103b7366004614054565b610c8a565b6040516103c9919061407f565b60405180910390f35b3480156103de57600080fd5b506103e8600a5481565b6040516103c99190614093565b34801561040157600080fd5b5061040a610d5b565b6040516103c991906140ff565b34801561042357600080fd5b50610437610432366004614128565b610ded565b6040516103c99190614163565b34801561045057600080fd5b5061046461045f366004614185565b610e4a565b005b34801561047257600080fd5b506104646104813660046141c2565b610f0a565b34801561049257600080fd5b50610464611082565b3480156104a757600080fd5b506104b0600381565b6040516103c991906141ed565b3480156104c957600080fd5b506104646104d83660046141fb565b61158a565b3480156104e957600080fd5b506104b0602081565b3480156104fe57600080fd5b506103e86000546001600160801b0370010000000000000000000000000000000082048116918116919091031690565b34801561053a57600080fd5b506103bc611617565b34801561054f57600080fd5b506105777f00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea8581565b6040516103c9919061425e565b34801561059057600080fd5b506104b061059f366004614128565b611632565b3480156105b057600080fd5b506105c46105bf366004614128565b611666565b6040516103c993929190614287565b3480156105df57600080fd5b506104646105ee3660046143b4565b6116b0565b3480156105ff57600080fd5b506015546106149067ffffffffffffffff1681565b6040516103c99190614412565b34801561062d57600080fd5b50610464611744565b34801561064257600080fd5b50610464610651366004614420565b6118b3565b34801561066257600080fd5b506104646118be565b34801561067757600080fd5b506103e8610686366004614185565b6119a0565b34801561069757600080fd5b506105777f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e6990981565b3480156106cb57600080fd5b50610464611ab6565b3480156106e057600080fd5b506104646106ef366004614420565b611f69565b34801561070057600080fd5b5061046461070f366004614470565b611f84565b34801561072057600080fd5b5061046461072f366004614185565b611ff9565b34801561074057600080fd5b506103bc61074f366004614128565b6120df565b34801561076057600080fd5b506103e861076f366004614128565b6120ea565b34801561078057600080fd5b506105777f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca81565b3480156107b457600080fd5b5061084b6107c3366004614128565b6016602090815260009182526040918290208251606081018452815461ffff808216835268ffffffffffffffffff620100008304168386015260ff6b0100000000000000000000009092048216151583870152600184015486518088019097526002909401546001600160a01b0381168752600160a01b900416938501939093529291169083565b6040516103c9939291906144e5565b34801561086657600080fd5b50610437610875366004614128565b6121ae565b34801561088657600080fd5b50600a5415156103bc565b34801561089d57600080fd5b506103e86108ac3660046141fb565b6121c0565b3480156108bd57600080fd5b50610464612228565b3480156108d257600080fd5b506103bc6108e1366004614128565b60136020526000908152604090205460ff1681565b34801561090257600080fd5b5061046461225e565b34801561091757600080fd5b506103bc610926366004614128565b612636565b34801561093757600080fd5b506103e8610946366004614128565b612673565b34801561095757600080fd5b50601154610577906001600160a01b031681565b34801561097757600080fd5b506007546001600160a01b0316610437565b34801561099557600080fd5b5061040a612694565b3480156109aa57600080fd5b506103e860185481565b3480156109c057600080fd5b506104646109cf366004614520565b6126a3565b3480156109e057600080fd5b506109e9612755565b6040516103c991906145e3565b348015610a0257600080fd5b50600b54610a689061ffff808216916201000081048216916401000000008204169062ffffff66010000000000008204169068ffffffffffffffffff69010000000000000000008204811691720100000000000000000000000000000000000090041686565b6040516103c9969594939291906145ff565b348015610a8657600080fd5b50610a9a610a95366004614128565b6128e7565b6040516103c9919061476a565b348015610ab357600080fd5b50610464612a40565b348015610ac857600080fd5b50610464610ad7366004614812565b612aaf565b348015610ae857600080fd5b50601054610437906001600160a01b031681565b348015610b0857600080fd5b5061040a610b17366004614128565b612ae9565b348015610b2857600080fd5b50610464610b373660046148b0565b612bfb565b348015610b4857600080fd5b506103e860095481565b348015610b5e57600080fd5b506104377f0000000000000000000000002efa2743b863f3bd6f624ac0d58445bc5fb62bf681565b348015610b9257600080fd5b50610464610ba1366004614923565b612e54565b610464610bb43660046143b4565b612eb1565b348015610bc557600080fd5b506103bc610bd436600461496b565b6001600160a01b03918216600090815260066020908152604080832093909416825291909152205460ff1690565b348015610c0e57600080fd5b50610464610c1d3660046141fb565b613205565b348015610c2e57600080fd5b506105777f0000000000000000000000002efa2743b863f3bd6f624ac0d58445bc5fb62bf681565b348015610c6257600080fd5b506103e87f9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded8680581565b60006001600160e01b031982167f80ac58cd000000000000000000000000000000000000000000000000000000001480610ced57506001600160e01b031982167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610d2157506001600160e01b031982167f780e9d6300000000000000000000000000000000000000000000000000000000145b80610d5557507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316145b92915050565b606060018054610d6a906149b4565b80601f0160208091040260200160405190810160405280929190818152602001828054610d96906149b4565b8015610de35780601f10610db857610100808354040283529160200191610de3565b820191906000526020600020905b815481529060010190602001808311610dc657829003601f168201915b5050505050905090565b6000610df882613261565b610e2e576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506000908152600560205260409020546001600160a01b031690565b6000610e55826121ae565b9050806001600160a01b0316836001600160a01b03161415610ea3576040517f943f7b8c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b336001600160a01b03821614801590610ec35750610ec18133610bd4565b155b15610efa576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f05838383613295565b505050565b60026008541415610f365760405162461bcd60e51b8152600401610f2d90614a0d565b60405180910390fd5b6002600855600d546040517f6352211e00000000000000000000000000000000000000000000000000000000815233917f00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea856001600160a01b031691636352211e91610fa391600401614093565b602060405180830381865afa158015610fc0573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610fe49190614a28565b6001600160a01b031614611024576040517fb2c6179c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600e54821461105f576040517f8f6d9d6300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600f54611079906110729060ff166132fe565b3383613339565b50506001600855565b600260085414156110a55760405162461bcd60e51b8152600401610f2d90614a0d565b600260085560175460155467ffffffffffffffff166110f0576040517f15cd15ad00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6110f86135f9565b61112e576040517fc3a7d74d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600054611145906001600160801b03166001614a5f565b6001600160801b0316600c828154811061116157611161614a97565b60009182526020909120015461ffff161015611581576000600c828154811061118c5761118c614a97565b6000918252602090912001546b010000000000000000000000900460ff1680156111d35750600b546009546111d0916601000000000000900462ffffff1690614aad565b42105b806111e25750600f5460ff1682145b156111f7576111f0826132fe565b90506112dd565b6015546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699091691635d3b1d3091611297917f9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded868059167ffffffffffffffff909116906005906207a12090600190600401614aee565b6020604051808303816000875af11580156112b6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112da9190614b45565b90505b600c82815481106112f0576112f0614a97565b6000918252602082200154601880546201000090920468ffffffffffffffffff1692909161131f908490614aad565b925050819055506040518060600160405280600c848154811061134457611344614a97565b6000918252602080832060408051606081018252939091015461ffff80821685526201000080830468ffffffffffffffffff908116878701526b0100000000000000000000009384900460ff161515878601529588528785018790528351808501855287815280860188905297840197909752888652601684529482902087518051825482870151928601519189166affffffffffffffffffffff199091161791909616909702969096176bff00000000000000000000001916931515029290921784558481015160018501805460ff191691151591909117905593015180516002909301805491909401516001600160a01b0390931675ffffffffffffffffffffffffffffffffffffffffffff1990911617600160a01b9290911691909102179055600c805482917fb40531e03f8d4be5f5bb24f4d1811140fbead25a449a04cdb8e941384a810702918590811061149f5761149f614a97565b906000526020600020016040516114b69190614be8565b60405180910390a2816114c881614bf6565b60178054600181810183556000929092527fc624b66cc0138b8fabc209247f72d758e1cf3343756d543badbf24212bed8c1501849055600c5491945061150f925090614c11565b821480156115355750600b54600a546115329162010000900461ffff1690614aad565b42105b15611541575050611583565b600c5482141561157b576040517fc4f545db975f34de8f12b4353fa42dd295e802239df19ebbe5fd3c245dad0a5a90600090a15050611583565b5061112e565b505b6001600855565b6007546001600160a01b031633146115b45760405162461bcd60e51b8152600401610f2d90614c5c565b601080546001600160a01b03831673ffffffffffffffffffffffffffffffffffffffff19918216811790925560118054909116821790556040517f2926c01a1380ae82a404a8c554ad486a6842a4a320d80b770e2930d763825e4f90600090a250565b600060095460001415801561162d575060095442115b905090565b6012818154811061164257600080fd5b9060005260206000209060209182820401919006915054906101000a900460ff1681565b600c818154811061167657600080fd5b60009182526020909120015461ffff8116915062010000810468ffffffffffffffffff16906b010000000000000000000000900460ff1683565b336001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909161461173657337f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699096040517f1cf993f4000000000000000000000000000000000000000000000000000000008152600401610f2d929190614c6c565b6117408282613699565b5050565b6007546001600160a01b0316331461176e5760405162461bcd60e51b8152600401610f2d90614c5c565b600a546117a7576040517fe5b93aca00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b54600a546117bb9161ffff1690614aad565b4210156117f4576040517f3e8e963c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6040514790600090339083908381818185875af1925050503d8060008114611838576040519150601f19603f3d011682016040523d82523d6000602084013e61183d565b606091505b5050905080611878576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4e70a604b23a8edee2b1d0a656e9b9c00b73ad8bb1afc2c59381ee9f69197de7826040516118a79190614093565b60405180910390a15050565b610f0583838361372c565b6007546001600160a01b031633146118e85760405162461bcd60e51b8152600401610f2d90614c5c565b6015546040517fd7ae1d300000000000000000000000000000000000000000000000000000000081526001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909169163d7ae1d309161195b9167ffffffffffffffff16903390600401614c87565b600060405180830381600087803b15801561197557600080fd5b505af1158015611989573d6000803e3d6000fd5b50506015805467ffffffffffffffff191690555050565b60006119ab836121c0565b82106119e3576040517f0ddac30e00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080546001600160801b03169080805b83811015611ab057600081815260036020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff161580159282019290925290611a5c5750611aa8565b80516001600160a01b031615611a7157805192505b876001600160a01b0316836001600160a01b03161415611aa65786841415611a9f57509350610d5592505050565b6001909301925b505b6001016119f4565b50600080fd5b6007546001600160a01b03163314611ae05760405162461bcd60e51b8152600401610f2d90614c5c565b611ae86135f9565b15611b1e576040517fa8ad87cbcccddb5ba11ee5851b9075d95af2c88adb9ad0ae9a4f40b810b74cb590600090a1611b1e611082565b601754479060005b81811015611bc5576016600060178381548110611b4557611b45614a97565b6000918252602080832090910154835282019290925260400190206001015460ff16611bbd576016600060178381548110611b8257611b82614a97565b60009182526020808320909101548352820192909252604001902054611bba9068ffffffffffffffffff620100009091041684614c11565b92505b600101611b26565b508180611bfe576040517f356680b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006014547f0000000000000000000000002efa2743b863f3bd6f624ac0d58445bc5fb62bf66001600160a01b03166318160ddd6040518163ffffffff1660e01b8152600401602060405180830381865afa158015611c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c859190614b45565b611c8f9190614c11565b600054600c546017549293506001600160801b03909116915b81811015611ea657600083600c8381548110611cc657611cc6614a97565b600091825260209091200154611ce0919061ffff16614c11565b905080851115611d5957600b54611d279068ffffffffffffffffff720100000000000000000000000000000000000082048116916901000000000000000000900416614cab565b611d3c9068ffffffffffffffffff1682614cce565b611d469089614aad565b9750611d528186614c11565b9450611df5565b600b546901000000000000000000900468ffffffffffffffffff16611d7e8683614c11565b611d889190614cce565b600b54611dc59068ffffffffffffffffff720100000000000000000000000000000000000082048116916901000000000000000000900416614cab565b611dda9068ffffffffffffffffff1687614cce565b611de49190614aad565b611dee9089614aad565b9750600094505b600c8281548110611e0857611e08614a97565b600091825260209091200154611e2f9062010000900468ffffffffffffffffff1689614c11565b97506001881015611e6c576040517f356680b700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b85881015611e78578795505b600c8281548110611e8b57611e8b614a97565b60009182526020909120015461ffff16935050600101611ca8565b50604051600090339086908381818185875af1925050503d8060008114611ee9576040519150601f19603f3d011682016040523d82523d6000602084013e611eee565b606091505b5050905080611f29576040517f27fcd9d100000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b7f4e70a604b23a8edee2b1d0a656e9b9c00b73ad8bb1afc2c59381ee9f69197de785604051611f589190614093565b60405180910390a150505050505050565b610f0583838360405180602001604052806000815250612aaf565b60026008541415611fa75760405162461bcd60e51b8152600401610f2d90614a0d565b60026008556007546001600160a01b03163314611fd65760405162461bcd60e51b8152600401610f2d90614c5c565b6000611fe1846132fe565b9050611fee818484613339565b505060016008555050565b6007546001600160a01b031633146120235760405162461bcd60e51b8152600401610f2d90614c5c565b600b546000548291640100000000900461ffff169061204c9083906001600160801b0316614aad565b1115612084576040517ffd59427a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60005460039061209d906001600160801b031684614aad565b11156120d5576040517f74a5d1f500000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610f058383613994565b6000610d5582613261565b600080546001600160801b031681805b8281101561217b57600081815260036020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff16151591810182905290612172578583141561216b5750949350505050565b6001909201915b506001016120fa565b506040517fa723001c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006121b982613a9b565b5192915050565b60006001600160a01b038216612202576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b506001600160a01b031660009081526004602052604090205467ffffffffffffffff1690565b6007546001600160a01b031633146122525760405162461bcd60e51b8152600401610f2d90614c5c565b61225c6000613bd8565b565b600260085414156122815760405162461bcd60e51b8152600401610f2d90614a0d565b600260085560175460005b818110156110795760166000601783815481106122ab576122ab614a97565b6000918252602080832090910154835282019290925260400190206001015460ff16158015612344575060166000601783815481106122ec576122ec614a97565b6000918252602080832090910154835282019290925260400190205460ff6b0100000000000000000000009091041615806123445750600b54600954612341916601000000000000900462ffffff1690614aad565b42115b1561262e576015546040517f5d3b1d300000000000000000000000000000000000000000000000000000000081526000916001600160a01b037f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699091691635d3b1d30916123ea917f9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded868059167ffffffffffffffff16906005906207a12090600190600401614aee565b6020604051808303816000875af1158015612409573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061242d9190614b45565b90506040518060600160405280601660006017868154811061245157612451614a97565b600091825260208083209190910154835282810193909352604091820181208251606081018452905461ffff80821683526201000080830468ffffffffffffffffff908116858901526b0100000000000000000000009384900460ff1615158588015293885287870185905285518087018752858152808801869052978601979097528884526016808752858520895180518254828b0151928a01519186166affffffffffffffffffffff199091161791909616909902989098176bff000000000000000000000019169315159092029290921786558685015160018701805460ff1916911515919091179055959092015180516002909501805491909401516001600160a01b0390951675ffffffffffffffffffffffffffffffffffffffffffff1990911617600160a01b9490921693909302179055601780548590811061259c5761259c614a97565b60009182526020808320909101548352820192909252604001902080547fffffffffffffffffffffffffffffffffffffffff00000000000000000000000016815560018101805460ff19169055600201805475ffffffffffffffffffffffffffffffffffffffffffff19169055601780548291908490811061262057612620614a97565b600091825260209091200155505b60010161228c565b60006012828154811061264b5761264b614a97565b6000918252602091829020918104909101546001601f9092166101000a900481161492915050565b6017818154811061268357600080fd5b600091825260209091200154905081565b606060028054610d6a906149b4565b6001600160a01b0382163314156126e6576040517fb06307db00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b3360008181526006602090815260408083206001600160a01b038716808552925291829020805460ff191685151517905590519091907f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c319061274990859061407f565b60405180910390a35050565b60175460609060009067ffffffffffffffff811115612776576127766142af565b6040519080825280602002602001820160405280156127e657816020015b6040805160c0810182526000606082018181526080830182905260a083018290528252602080830182905283518085018552828152808201929092529282015282526000199092019101816127945790505b50905060005b6017548110156128e157601660006017838154811061280d5761280d614a97565b600091825260208083209091015483528281019390935260409182019020815160c081018352815461ffff8082166060840190815268ffffffffffffffffff62010000840416608085015260ff6b0100000000000000000000009093048316151560a085015283526001840154909116151582860152835180850185526002909301546001600160a01b0381168452600160a01b900416938201939093529082015282518390839081106128c3576128c3614a97565b602002602001018190525080806128d990614bf6565b9150506127ec565b50919050565b6129126040518060800160405280606081526020016060815260200160608152602001606081525090565b61291b82613261565b612951576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546001600160a01b0316612993576040517f38bdd72700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601154601280546001600160a01b03909216916344ec3631918591829081106129be576129be614a97565b90600052602060002090602091828204019190069054906101000a900460ff166040518363ffffffff1660e01b81526004016129fb929190614ced565b600060405180830381865afa158015612a18573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d559190810190614f4e565b6007546001600160a01b03163314612a6a5760405162461bcd60e51b8152600401610f2d90614c5c565b612a72611617565b15612aa9576040517fd205ec1b00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b42600955565b612aba84848461372c565b612ac684848484613c37565b612ae3576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b6060612af482613261565b612b2a576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6010546001600160a01b0316612b4e57505060408051602081019091526000815290565b601154601280546001600160a01b0390921691635cc518ba91859182908110612b7957612b79614a97565b90600052602060002090602091828204019190069054906101000a900460ff166040518363ffffffff1660e01b8152600401612bb6929190614ced565b600060405180830381865afa158015612bd3573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052610d559190810190614f89565b60026008541415612c1e5760405162461bcd60e51b8152600401610f2d90614a0d565b600260085560155467ffffffffffffffff16612d72577f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699096001600160a01b031663a21a23e46040518163ffffffff1660e01b81526004016020604051808303816000875af1158015612c94573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612cb89190614fdf565b6015805467ffffffffffffffff191667ffffffffffffffff9290921691821790556040517f7341c10c0000000000000000000000000000000000000000000000000000000081527f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e699096001600160a01b031691637341c10c91612d3f91903090600401614c87565b600060405180830381600087803b158015612d5957600080fd5b505af1158015612d6d573d6000803e3d6000fd5b505050505b6015546040516001600160a01b037f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca1691634000aea0917f000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909918591612de49167ffffffffffffffff1690602001614412565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612e1193929190615023565b6020604051808303816000875af1158015612e30573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611079919061505b565b60026008541415612e775760405162461bcd60e51b8152600401610f2d90614a0d565b60026008558060005b81811015611fee57612ea9848483818110612e9d57612e9d614a97565b90506020020135613d69565b600101612e80565b612eb9611617565b612eef576040517f63a2de0f00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600b546000548391640100000000900461ffff1690612f189083906001600160801b0316614aad565b1115612f50576040517ffd59427a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026008541415612f735760405162461bcd60e51b8152600401610f2d90614a0d565b6002600855600b54600090612fa19085906901000000000000000000900468ffffffffffffffffff16614cce565b8351909150600090815b8181101561319957336001600160a01b03167f0000000000000000000000002efa2743b863f3bd6f624ac0d58445bc5fb62bf66001600160a01b0316636352211e888481518110612ffe57612ffe614a97565b60200260200101516040518263ffffffff1660e01b81526004016130229190614093565b602060405180830381865afa15801561303f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906130639190614a28565b6001600160a01b0316146130a3576040517f5246352300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b601360008783815181106130b9576130b9614a97565b60209081029190910181015182528101919091526040016000205460ff161580156130e357508683105b156131915760016013600088848151811061310057613100614a97565b6020026020010151815260200190815260200160002060006101000a81548160ff021916908315150217905550828061313890614bf6565b600b54909450613179915068ffffffffffffffffff720100000000000000000000000000000000000082048116916901000000000000000000900416614cab565b61318e9068ffffffffffffffffff1685614c11565b93505b600101612fab565b5081601460008282546131ac9190614aad565b90915550503483146131ee5782346040517f6871963e000000000000000000000000000000000000000000000000000000008152600401610f2d92919061507c565b6131f83387613994565b5050600160085550505050565b6007546001600160a01b0316331461322f5760405162461bcd60e51b8152600401610f2d90614c5c565b6001600160a01b0381166132555760405162461bcd60e51b8152600401610f2d90615097565b61325e81613bd8565b50565b600080546001600160801b031682108015610d55575050600090815260036020526040902054600160e01b900460ff161590565b600082815260056020526040808220805473ffffffffffffffffffffffffffffffffffffffff19166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061330b60ff836150f8565b60405160200161331b9190615124565b60408051601f19818403018152919052805160209091012092915050565b60008381526016602052604090206001015460ff1615613385576040517f636d49d300000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526016602052604090205462010000900468ffffffffffffffffff166133db576040517f8e1773d800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b816001600160a01b03166133ee826121ae565b6001600160a01b03161461342e576040517f03e21ec200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526016602052604090205461344d9060019061ffff16615136565b61ffff1681111561348a576040517f518af55d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008381526016602081815260408084206001818101805460ff19169091179055815180830183526001600160a01b0380891680835261ffff808a168488019081528c8a529790965282516002850180549851909716600160a01b0275ffffffffffffffffffffffffffffffffffffffffffff19909816921691909117959095179093555490519193929168ffffffffffffffffff62010000909204919091169060006040518083038185875af1925050503d8060008114613568576040519150601f19603f3d011682016040523d82523d6000602084013e61356d565b606091505b50509050806135a8576040517f90b8ec1800000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60008581526016602052604090819020905186917f7d2db4ed55b360e8ea7d70390d6f63a1404136410fa6f3f94a41d1cf99488a7f916135ea91908690615144565b60405180910390a25050505050565b600c54601754600091141561360e5750600090565b600c5461361d90600190614c11565b6017541480156136455750600b54600a546136429162010000900461ffff1690614aad565b42105b156136505750600090565b600054601754600c80546001600160801b0390931692909190811061367757613677614a97565b60009182526020909120015461ffff1611156136935750600090565b50600190565b60008281526016602052604090205461ffff16806136e3576040517f018bd28900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081836000815181106136f9576136f9614a97565b602002602001015161370b91906150f8565b90506000613718826121ae565b9050613725858284613339565b5050505050565b600061373782613a9b565b80519091506000906001600160a01b0316336001600160a01b03161480613765575081516137659033610bd4565b8061378057503361377584610ded565b6001600160a01b0316145b9050806137b9576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b846001600160a01b031682600001516001600160a01b031614613808576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038416613848576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6138586000848460000151613295565b6001600160a01b038581166000908152600460209081526040808320805467ffffffffffffffff1980821667ffffffffffffffff92831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600390945282852080546001600160e01b031916909417600160a01b42909216919091021790925590860180835291205490911661394d576000546001600160801b031681101561394d578251600082815260036020908152604090912080549186015167ffffffffffffffff16600160a01b026001600160e01b03199092166001600160a01b03909316929092171790555b5082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613725565b60208111156139cf576040517f359fd04400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600081333442446040516020016139ea959493929190615187565b60405160208183030381529060405280519060200120905060005b82811015613a635760126001838360208110613a2357613a23614a97565b83546001808201865560009586526020958690209582049095018054601f9092166101000a60ff818102199093169490931a90941b160217905501613a05565b50613a6e8383613e29565b600b5460005464010000000090910461ffff166001600160801b039091161415610f055742600a55505050565b60408051606081018252600080825260208201819052918101829052905482906001600160801b0316811015613ba657600081815260036020908152604091829020825160608101845290546001600160a01b0381168252600160a01b810467ffffffffffffffff1692820192909252600160e01b90910460ff16151591810182905290613ba45780516001600160a01b031615613b3a579392505050565b5060001901600081815260036020908152604091829020825160608101845290546001600160a01b038116808352600160a01b820467ffffffffffffffff1693830193909352600160e01b900460ff1615159281019290925215613b9f579392505050565b613b3a565b505b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600780546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006001600160a01b0384163b15613d5d576040517f150b7a020000000000000000000000000000000000000000000000000000000081526001600160a01b0385169063150b7a0290613c949033908990889088906004016151d1565b6020604051808303816000875af1925050508015613ccf575060408051601f3d908101601f19168201909252613ccc91810190615216565b60015b613d2a573d808015613cfd576040519150601f19603f3d011682016040523d82523d6000602084013e613d02565b606091505b508051613d22576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b0319167f150b7a0200000000000000000000000000000000000000000000000000000000149050613d61565b5060015b949350505050565b33613d73826121ae565b6001600160a01b031614613db3576040517fff68d35d00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60128181548110613dc657613dc6614a97565b90600052602060002090602091828204019190069054906101000a900460ff1660011860128281548110613dfc57613dfc614a97565b90600052602060002090602091828204019190066101000a81548160ff021916908360ff16021790555050565b611740828260405180602001604052806000815250610f0583838360016000546001600160801b03166001600160a01b038516613e92576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b83613ec9576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6001600160a01b038516600081815260046020908152604080832080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000811667ffffffffffffffff8083168c0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168c018116909202179091558584526003909252822080546001600160e01b031916909317600160a01b42909216919091021790915581905b85811015613ff45760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4838015613fca5750613fc86000888488613c37565b155b15613fe8576040516368d2bf6b60e11b815260040160405180910390fd5b60019182019101613f73565b50600080547fffffffffffffffffffffffffffffffff00000000000000000000000000000000166001600160801b0392909216919091179055613725565b6001600160e01b031981165b811461325e57600080fd5b8035610d5581614032565b60006020828403121561406957614069600080fd5b6000613d618484614049565b8015155b82525050565b60208101610d558284614075565b80614079565b60208101610d55828461408d565b60005b838110156140bc5781810151838201526020016140a4565b83811115612ae35750506000910152565b60006140d7825190565b8084526020840193506140ee8185602086016140a1565b601f01601f19169290920192915050565b6020808252810161411081846140cd565b9392505050565b8061403e565b8035610d5581614117565b60006020828403121561413d5761413d600080fd5b6000613d61848461411d565b60006001600160a01b038216610d55565b61407981614149565b60208101610d55828461415a565b61403e81614149565b8035610d5581614171565b6000806040838503121561419b5761419b600080fd5b60006141a7858561417a565b92505060206141b88582860161411d565b9150509250929050565b600080604083850312156141d8576141d8600080fd5b60006141a7858561411d565b60ff8116614079565b60208101610d5582846141e4565b60006020828403121561421057614210600080fd5b6000613d61848461417a565b6000610d556001600160a01b038316614233565b90565b6001600160a01b031690565b6000610d558261421c565b6000610d558261423f565b6140798161424a565b60208101610d558284614255565b61ffff8116614079565b68ffffffffffffffffff8116614079565b60608101614295828661426c565b6142a26020830185614276565b613d616040830184614075565b634e487b7160e01b600052604160045260246000fd5b601f19601f830116810181811067ffffffffffffffff821117156142eb576142eb6142af565b6040525050565b60006142fd60405190565b905061430982826142c5565b919050565b600067ffffffffffffffff821115614328576143286142af565b5060209081020190565b60006143456143408461430e565b6142f2565b8381529050602080820190840283018581111561436457614364600080fd5b835b8181101561438657614378878261411d565b835260209283019201614366565b5050509392505050565b600082601f8301126143a4576143a4600080fd5b8135613d61848260208601614332565b600080604083850312156143ca576143ca600080fd5b60006143d6858561411d565b925050602083013567ffffffffffffffff8111156143f6576143f6600080fd5b6141b885828601614390565b67ffffffffffffffff8116614079565b60208101610d558284614402565b60008060006060848603121561443857614438600080fd5b6000614444868661417a565b93505060206144558682870161417a565b92505060406144668682870161411d565b9150509250925092565b60008060006060848603121561448857614488600080fd5b6000614444868661411d565b80516144a0838261426c565b5060208101516144b36020840182614276565b506040810151610f056040840182614075565b80516144d2838261415a565b506020810151610f05602084018261426c565b60c081016144f38286614494565b6145006060830185614075565b613d6160808301846144c6565b80151561403e565b8035610d558161450d565b6000806040838503121561453657614536600080fd5b6000614542858561417a565b92505060206141b885828601614515565b805161455f8382614494565b5060208101516145726060840182614075565b506040810151610f0560808401826144c6565b61458f8282614553565b5060c00190565b60200190565b60006145a6825190565b808452602093840193830160005b828110156145d95781516145c88782614585565b9650506020820191506001016145b4565b5093949350505050565b60208082528101614110818461459c565b62ffffff8116614079565b60c0810161460d828961426c565b61461a602083018861426c565b614627604083018761426c565b61463460608301866145f4565b6146416080830185614276565b61464e60a0830184614276565b979650505050505050565b805160408084526000919084019061467182826140cd565b9150506020830151848203602086015261468b82826140cd565b95945050505050565b60006141108383614659565b60006146aa825190565b808452602084019350836020820285016146c48560200190565b60005b848110156146f857838303885281516146e08482614694565b935050602082016020989098019791506001016146c7565b50909695505050505050565b805160808084526000919084019061471c82826140cd565b9150506020830151848203602086015261473682826140cd565b9150506040830151848203604086015261475082826140cd565b9150506060830151848203606086015261468b82826146a0565b602080825281016141108184614704565b600067ffffffffffffffff821115614795576147956142af565b601f19601f83011660200192915050565b82818337506000910152565b60006147c06143408461477b565b9050828152602081018484840111156147db576147db600080fd5b6147e68482856147a6565b509392505050565b600082601f83011261480257614802600080fd5b8135613d618482602086016147b2565b6000806000806080858703121561482b5761482b600080fd5b6000614837878761417a565b94505060206148488782880161417a565b93505060406148598782880161411d565b925050606085013567ffffffffffffffff81111561487957614879600080fd5b614885878288016147ee565b91505092959194509250565b6bffffffffffffffffffffffff811661403e565b8035610d5581614891565b6000602082840312156148c5576148c5600080fd5b6000613d6184846148a5565b60008083601f8401126148e6576148e6600080fd5b50813567ffffffffffffffff81111561490157614901600080fd5b60208301915083602082028301111561491c5761491c600080fd5b9250929050565b6000806020838503121561493957614939600080fd5b823567ffffffffffffffff81111561495357614953600080fd5b61495f858286016148d1565b92509250509250929050565b6000806040838503121561498157614981600080fd5b600061498d858561417a565b92505060206141b88582860161417a565b634e487b7160e01b600052602260045260246000fd5b6002810460018216806149c857607f821691505b602082108114156128e1576128e161499e565b601f8152602081017f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0081529050614596565b60208082528101610d55816149db565b8051610d5581614171565b600060208284031215614a3d57614a3d600080fd5b6000613d618484614a1d565b634e487b7160e01b600052601160045260246000fd5b6001600160801b03811690506001600160801b03821691506000826001600160801b0303821115614a9257614a92614a49565b500190565b634e487b7160e01b600052603260045260246000fd5b60008219821115614a9257614a92614a49565b6000610d55825b61ffff1690565b61407981614ac0565b600063ffffffff8216610d55565b61407981614ad7565b60a08101614afc828861408d565b614b096020830187614402565b614b166040830186614ace565b614b236060830185614ae5565b614b306080830184614ae5565b9695505050505050565b8051610d5581614117565b600060208284031215614b5a57614b5a600080fd5b6000613d618484614b3a565b6000610d5582614ac7565b6000610d55614b808360101c90565b68ffffffffffffffffff1690565b6000610d55614b9d8360581c90565b60ff1690565b8054614bae81614b66565b614bb8848261426c565b50614bc281614b71565b614bcf6020850182614276565b50614bd981614b8e565b9050610f056040840182614075565b60608101610d558284614ba3565b6000600019821415614c0a57614c0a614a49565b5060010190565b815b9150600082821015614c2757614c27614a49565b500390565b60208082527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65729101908152614596565b60208082528101610d5581614c2c565b60408101614c7a828561415a565b614110602083018461415a565b60408101614c7a8285614402565b634e487b7160e01b600052601260045260246000fd5b68ffffffffffffffffff9182169116600082614cc957614cc9614c95565b500490565b6000816000190483118215151615614ce857614ce8614a49565b500290565b60408101614cfb828561408d565b61411060208301846141e4565b6000614d166143408461477b565b905082815260208101848484011115614d3157614d31600080fd5b6147e68482856140a1565b600082601f830112614d5057614d50600080fd5b8151613d61848260208601614d08565b600060408284031215614d7557614d75600080fd5b614d7f60406142f2565b825190915067ffffffffffffffff811115614d9c57614d9c600080fd5b614da884828501614d3c565b825250602082015167ffffffffffffffff811115614dc857614dc8600080fd5b614dd484828501614d3c565b60208301525092915050565b6000614dee6143408461430e565b83815290506020808201908402830185811115614e0d57614e0d600080fd5b835b8181101561438657805167ffffffffffffffff811115614e3157614e31600080fd5b8501614e3d8882614d60565b84525060209283019201614e0f565b600082601f830112614e6057614e60600080fd5b8151613d61848260208601614de0565b600060808284031215614e8557614e85600080fd5b614e8f60806142f2565b825190915067ffffffffffffffff811115614eac57614eac600080fd5b614eb884828501614d3c565b825250602082015167ffffffffffffffff811115614ed857614ed8600080fd5b614ee484828501614d3c565b602083015250604082015167ffffffffffffffff811115614f0757614f07600080fd5b614f1384828501614d3c565b604083015250606082015167ffffffffffffffff811115614f3657614f36600080fd5b614f4284828501614e4c565b60608301525092915050565b600060208284031215614f6357614f63600080fd5b815167ffffffffffffffff811115614f7d57614f7d600080fd5b613d6184828501614e70565b600060208284031215614f9e57614f9e600080fd5b815167ffffffffffffffff811115614fb857614fb8600080fd5b613d6184828501614d3c565b67ffffffffffffffff811661403e565b8051610d5581614fc4565b600060208284031215614ff457614ff4600080fd5b6000613d618484614fd4565b6000610d556142306bffffffffffffffffffffffff841681565b61407981615000565b60608101615031828661415a565b61503e602083018561501a565b818103604083015261468b81846140cd565b8051610d558161450d565b60006020828403121561507057615070600080fd5b6000613d618484615050565b6040810161508a828561408d565b614110602083018461408d565b60208082528101610d5581602681527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160208201527f6464726573730000000000000000000000000000000000000000000000000000604082015260600190565b60008261510757615107614c95565b500690565b6000610d558260f81b90565b61407960ff821661510c565b61512e8183615118565b600101919050565b61ffff908116908216614c13565b60a081016151528285614ba3565b61411060608301846144c6565b6000610d558260601b90565b6000610d558261515f565b61407961518282614149565b61516b565b615191818761408d565b60200161519e8186615176565b6014016151ab818561408d565b6020016151b8818461408d565b6020016151c5818361408d565b60200195945050505050565b608081016151df828761415a565b6151ec602083018661415a565b6151f9604083018561408d565b8181036060830152614b3081846140cd565b8051610d5581614032565b60006020828403121561522b5761522b600080fd5b6000613d61848461520b56fea26469706673582212207dd66c8d317298ce56e6a7158ceeab1e7aba2a50e9aee48f85e7c4089ad87e4864736f6c634300080c0033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000000000000000000000000000000000000000000240000000000000000000000000000000000000000000000000000000000000028000000000000000000000000004af8975918169ae48b25da78d5145bd673b2b6e000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded868050000000000000000000000000000000000000000000000000000000000001c200000000000000000000000000000000000000000000000000000000000000e100000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000000000000000024ea0000000000000000000000000000000000000000000000000000b1a2bc2ec50000000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000002c000000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea850000000000000000000000002efa2743b863f3bd6f624ac0d58445bc5fb62bf66f4b4baf771f79ee3db2afdf13c35c213ea9f36f199efb86410649ffdf1adb0e000000000000000000000000000000000000000000000000000000000000002a0000000000000000000000000000000000000000000000000000000000000014000000000000000000000000000000000000000000000000000000000000000b436f2d426f747320322e3000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044342544500000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f00000000000000000000000000000000000000000000000000000000000000640000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000c80000000000000000000000000000000000000000000000001bc16d674ec800000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000012c00000000000000000000000000000000000000000000000029a2241af62c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001900000000000000000000000000000000000000000000000003782dace9d900000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000002ee00000000000000000000000000000000000000000000000053444835ec580000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000003e80000000000000000000000000000000000000000000000006124fee993bc0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005dc0000000000000000000000000000000000000000000000006f05b59d3b200000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000007ce66c50e284000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000bb80000000000000000000000000000000000000000000000001bc16d674ec8000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000fa0000000000000000000000000000000000000000000000000a688906bd8b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000000c249fdd32778000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001388000000000000000000000000000000000000000000000002b5e3af16b188000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001770000000000000000000000000000000000000000000000000de0b6b3a7640000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001b58000000000000000000000000000000000000000000000000f9ccd8a1c508000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000001f400000000000000000000000000000000000000000000000003782dace9d90000000000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002328000000000000000000000000000000000000000000000001314fb37062980000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000027100000000000000000000000000000000000000000000000014d1120d7b160000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002710000000000000000000000000000000000000000000000003bd913e6c1df400000000000000000000000000000000000000000000000000000000000000000000
-----Decoded View---------------
Arg [0] : name_ (string): Co-Bots 2.0
Arg [1] : symbol_ (string): CBTE
Arg [2] : _rendererAddress (address): 0x04af8975918169Ae48B25DA78D5145BD673B2b6E
Arg [3] : vrfCoordinator (address): 0x271682DEB8C4E0901D1a1550aD2e64D568E69909
Arg [4] : link (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [5] : keyHash (bytes32): 0x9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805
Arg [6] : _parameters (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [7] : _prizes (tuple[]): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput],System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
Arg [8] : ens (address): 0x57f1887a8BF19b14fC0dF6Fd9B2acc9Af147eA85
Arg [9] : cobotsV1 (address): 0x2eFa2743B863F3Bd6f624Ac0d58445bC5fB62bf6
Arg [10] : _mysteryChallenge (tuple): System.Collections.Generic.List`1[Nethereum.ABI.FunctionEncoding.ParameterOutput]
-----Encoded View---------------
116 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000240
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000280
Arg [2] : 00000000000000000000000004af8975918169ae48b25da78d5145bd673b2b6e
Arg [3] : 000000000000000000000000271682deb8c4e0901d1a1550ad2e64d568e69909
Arg [4] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [5] : 9fe0eebf5e446e3c998ec9bb19951541aee00bb90ea201ae456421a2ded86805
Arg [6] : 0000000000000000000000000000000000000000000000000000000000001c20
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000e10
Arg [8] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [9] : 000000000000000000000000000000000000000000000000000000000024ea00
Arg [10] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [12] : 00000000000000000000000000000000000000000000000000000000000002c0
Arg [13] : 00000000000000000000000057f1887a8bf19b14fc0df6fd9b2acc9af147ea85
Arg [14] : 0000000000000000000000002efa2743b863f3bd6f624ac0d58445bc5fb62bf6
Arg [15] : 6f4b4baf771f79ee3db2afdf13c35c213ea9f36f199efb86410649ffdf1adb0e
Arg [16] : 000000000000000000000000000000000000000000000000000000000000002a
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000014
Arg [18] : 000000000000000000000000000000000000000000000000000000000000000b
Arg [19] : 436f2d426f747320322e30000000000000000000000000000000000000000000
Arg [20] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [21] : 4342544500000000000000000000000000000000000000000000000000000000
Arg [22] : 000000000000000000000000000000000000000000000000000000000000001f
Arg [23] : 0000000000000000000000000000000000000000000000000000000000000064
Arg [24] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [26] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [27] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [28] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [29] : 000000000000000000000000000000000000000000000000000000000000012c
Arg [30] : 00000000000000000000000000000000000000000000000029a2241af62c0000
Arg [31] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [32] : 0000000000000000000000000000000000000000000000000000000000000190
Arg [33] : 0000000000000000000000000000000000000000000000003782dace9d900000
Arg [34] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [35] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [36] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [37] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [38] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [39] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [40] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [41] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [42] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [43] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [44] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [45] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [46] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [47] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [48] : 0000000000000000000000000000000000000000000000000de0b6b3a7640000
Arg [49] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [50] : 00000000000000000000000000000000000000000000000000000000000002ee
Arg [51] : 00000000000000000000000000000000000000000000000053444835ec580000
Arg [52] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [53] : 00000000000000000000000000000000000000000000000000000000000003e8
Arg [54] : 0000000000000000000000000000000000000000000000006124fee993bc0000
Arg [55] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [56] : 00000000000000000000000000000000000000000000000000000000000005dc
Arg [57] : 0000000000000000000000000000000000000000000000006f05b59d3b200000
Arg [58] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [59] : 00000000000000000000000000000000000000000000000000000000000007d0
Arg [60] : 0000000000000000000000000000000000000000000000007ce66c50e2840000
Arg [61] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [62] : 0000000000000000000000000000000000000000000000000000000000000bb8
Arg [63] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [64] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [65] : 0000000000000000000000000000000000000000000000000000000000000bb8
Arg [66] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [67] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [68] : 0000000000000000000000000000000000000000000000000000000000000bb8
Arg [69] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [70] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [71] : 0000000000000000000000000000000000000000000000000000000000000bb8
Arg [72] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [73] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [74] : 0000000000000000000000000000000000000000000000000000000000000bb8
Arg [75] : 0000000000000000000000000000000000000000000000001bc16d674ec80000
Arg [76] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [77] : 0000000000000000000000000000000000000000000000000000000000000fa0
Arg [78] : 000000000000000000000000000000000000000000000000a688906bd8b00000
Arg [79] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [80] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [81] : 000000000000000000000000000000000000000000000000c249fdd327780000
Arg [82] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [83] : 0000000000000000000000000000000000000000000000000000000000001388
Arg [84] : 000000000000000000000000000000000000000000000002b5e3af16b1880000
Arg [85] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [86] : 0000000000000000000000000000000000000000000000000000000000001770
Arg [87] : 000000000000000000000000000000000000000000000000de0b6b3a76400000
Arg [88] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [89] : 0000000000000000000000000000000000000000000000000000000000001b58
Arg [90] : 000000000000000000000000000000000000000000000000f9ccd8a1c5080000
Arg [91] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [92] : 0000000000000000000000000000000000000000000000000000000000001f40
Arg [93] : 0000000000000000000000000000000000000000000000003782dace9d900000
Arg [94] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [95] : 0000000000000000000000000000000000000000000000000000000000001f40
Arg [96] : 0000000000000000000000000000000000000000000000003782dace9d900000
Arg [97] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [98] : 0000000000000000000000000000000000000000000000000000000000001f40
Arg [99] : 0000000000000000000000000000000000000000000000003782dace9d900000
Arg [100] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [101] : 0000000000000000000000000000000000000000000000000000000000001f40
Arg [102] : 0000000000000000000000000000000000000000000000003782dace9d900000
Arg [103] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [104] : 0000000000000000000000000000000000000000000000000000000000001f40
Arg [105] : 0000000000000000000000000000000000000000000000003782dace9d900000
Arg [106] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [107] : 0000000000000000000000000000000000000000000000000000000000002328
Arg [108] : 000000000000000000000000000000000000000000000001314fb37062980000
Arg [109] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [110] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [111] : 0000000000000000000000000000000000000000000000014d1120d7b1600000
Arg [112] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [113] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [114] : 000000000000000000000000000000000000000000000003bd913e6c1df40000
Arg [115] : 0000000000000000000000000000000000000000000000000000000000000000
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.