Overview
ETH Balance
3.336 ETH
Eth Value
$11,273.63 (@ $3,379.39/ETH)Token Holdings
Transaction Hash |
Method
|
Block
|
From
|
To
|
|||||
---|---|---|---|---|---|---|---|---|---|
0x7a13e790cdd0fcf0d0059830d710e15fe04a6d31a910eae6da6635cc82d72fe0 | Buy Entry | (pending) | 1 hr ago | IN | 0 ETH | (Pending) | |||
0x1c512a63dc9318671a43ee38b921317b2a2debe3bfd39894861e39695f69c975 | Buy Entry | (pending) | 3 days ago | IN | 0 ETH | (Pending) | |||
0xf69fbb4f29600f2e2d579ff3a0aa5fd20236e8d03ad30c35768253b7d6a76d11 | Buy Entry | (pending) | 19 days ago | IN | 0 ETH | (Pending) | |||
0x74ab21fafd5ff7ed3d58fc201ba98ff6d94a637ec0944725f0f8f18d74de6562 | Buy Entry | (pending) | 20 days ago | IN | 0 ETH | (Pending) | |||
Buy Entry | 21245558 | 12 hrs ago | IN | 0.006 ETH | 0.00083076 | ||||
Buy Entry | 21244711 | 15 hrs ago | IN | 0.006 ETH | 0.0010757 | ||||
Buy Entry | 21244211 | 17 hrs ago | IN | 0 ETH | 0.00098677 | ||||
Buy Entry | 21231613 | 2 days ago | IN | 0.096 ETH | 0.00097088 | ||||
Set Winner | 21231492 | 2 days ago | IN | 0 ETH | 0.00402329 | ||||
Buy Entry | 21231486 | 2 days ago | IN | 0.012 ETH | 0.00151489 | ||||
Buy Entry | 21231486 | 2 days ago | IN | 0 ETH | 0.00151489 | ||||
Buy Entry | 21231482 | 2 days ago | IN | 0.096 ETH | 0.00155419 | ||||
Buy Entry | 21231451 | 2 days ago | IN | 0.048 ETH | 0.00156765 | ||||
Buy Entry | 21231390 | 2 days ago | IN | 0.006 ETH | 0.00184538 | ||||
Buy Entry | 21231374 | 2 days ago | IN | 0.006 ETH | 0.00186131 | ||||
Buy Entry | 21231372 | 2 days ago | IN | 0.012 ETH | 0.00191586 | ||||
Buy Entry | 21231331 | 2 days ago | IN | 0.006 ETH | 0.00094559 | ||||
Buy Entry | 21231321 | 2 days ago | IN | 0.006 ETH | 0.00119874 | ||||
Buy Entry | 21231253 | 2 days ago | IN | 0 ETH | 0.00119317 | ||||
Buy Entry | 21231249 | 2 days ago | IN | 0.012 ETH | 0.00121601 | ||||
Buy Entry | 21231226 | 2 days ago | IN | 0.006 ETH | 0.00130607 | ||||
Buy Entry | 21231213 | 2 days ago | IN | 0 ETH | 0.00124026 | ||||
Buy Entry | 21231205 | 2 days ago | IN | 0.006 ETH | 0.00126471 | ||||
Buy Entry | 21231204 | 2 days ago | IN | 0.006 ETH | 0.00114273 | ||||
Buy Entry | 21231079 | 2 days ago | IN | 0.048 ETH | 0.00121732 |
Latest 25 internal transactions (View All)
Advanced mode:
Parent Transaction Hash | Block | From | To | |||
---|---|---|---|---|---|---|
21231503 | 2 days ago | 2.73 ETH | ||||
21231503 | 2 days ago | 3 ETH | ||||
21181328 | 9 days ago | 3.644 ETH | ||||
21181328 | 9 days ago | 3 ETH | ||||
21131167 | 16 days ago | 2.858 ETH | ||||
21131167 | 16 days ago | 3 ETH | ||||
21080711 | 23 days ago | 3.064 ETH | ||||
21080711 | 23 days ago | 3 ETH | ||||
21030552 | 30 days ago | 2.848 ETH | ||||
21030552 | 30 days ago | 3 ETH | ||||
20987544 | 36 days ago | 2.342 ETH | ||||
20987544 | 36 days ago | 3 ETH | ||||
20937475 | 43 days ago | 2.598 ETH | ||||
20937475 | 43 days ago | 3 ETH | ||||
20880075 | 51 days ago | 2.836 ETH | ||||
20880075 | 51 days ago | 3 ETH | ||||
20829875 | 58 days ago | 3.104 ETH | ||||
20829875 | 58 days ago | 3 ETH | ||||
20779737 | 65 days ago | 2.56 ETH | ||||
20779737 | 65 days ago | 3 ETH | ||||
20729626 | 72 days ago | 2.742 ETH | ||||
20729626 | 72 days ago | 3 ETH | ||||
20679477 | 79 days ago | 2.4 ETH | ||||
20679477 | 79 days ago | 3 ETH | ||||
20629346 | 86 days ago | 2.644 ETH |
Loading...
Loading
Contract Name:
ETHFixedLean
Compiler Version
v0.8.4+commit.c7e474f2
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
// SPDX-License-Identifier: UNLICENSED pragma solidity ^0.8.4; import "@openzeppelin/contracts/access/AccessControl.sol"; import "@chainlink/contracts/src/v0.8/VRFConsumerBase.sol"; import "@openzeppelin/contracts/utils/math/Math.sol"; /// @title Raffles manager (lean, single winner and a fixed amount of ETH as prize) /// @author Luis Pando /// @notice It consumes VRF v1 from Chainlink. It has the role /// "operator" that is the one used by a backend app to make some calls /// @dev It saves in an ordered array the player wallet and the current /// entries count. So buying entries has a complexity of O(1) /// For calculating the winner, from the huge random number generated by Chainlink /// a normalized random is generated by using the module method, adding 1 to have /// a random from 1 to entriesCount. /// So next step is to perform a binary search on the ordered array to get the /// player O(log n) /// Example: /// 0 -> { 1, player1} as player1 buys 1 entry /// 1 -> {51, player2} as player2 buys 50 entries /// 2 -> {52, player3} as player3 buys 1 entry /// 3 -> {53, player4} as player4 buys 1 entry /// 4 -> {153, player5} as player5 buys 100 entries /// So the setWinner method performs a binary search on that sorted array to get the upper bound. /// If the random number generated is 150, the winner is player5. If the random number is 20, winner is player2 contract ETHFixedLean is AccessControl, VRFConsumerBase { ////////// CHAINLINK VRF v1 ///////////////// bytes32 internal keyHash; // chainlink uint256 internal fee; // fee paid in LINK to chainlink. 0.1 in Rinkeby, 2 in mainnet struct RandomResult { uint256 randomNumber; // random number generated by chainlink. uint256 nomalizedRandomNumber; // random number % entriesLength + 1. So between 1 and entries.length } // event sent when the random number is generated by the VRF event RandomNumberCreated( uint256 indexed idFromMetawin, uint256 randomNumber, uint256 normalizedRandomNumber ); struct RaffleInfo { uint256 id; // raffleId uint256 size; // length of the entries array of that raffle } mapping(uint256 => RandomResult) public requests; // map the requestId created by chainlink with the raffle info passed as param when calling getRandomNumber() mapping(bytes32 => RaffleInfo) public chainlinkRaffleInfo; /////////////// END CHAINKINK VRF V1 ////////////// error EntryNotAllowed(string errorType); // Event sent when the raffle is created by the operator event RaffleCreated(uint256 indexed raffleId, uint256 indexed nftId); // Event sent when the owner of the nft stakes it for the raffle event RaffleStarted(uint256 indexed raffleId, address indexed seller); // Event sent when the raffle is finished (either early cashout or successful completion) event RaffleEnded( uint256 indexed raffleId, address indexed winner, uint256 amountRaised, uint256 randomNumber ); // Event sent when one or more entries are sold (info from the price structure) event EntrySold( uint256 indexed raffleId, address indexed buyer, uint256 currentSize, uint256 priceStructureId ); // Event sent when a free entry is added by the operator event FreeEntry( uint256 indexed raffleId, address[] buyer, uint256 amount, uint256 currentSize ); // Event sent when a raffle is asked to cancel by the operator event RaffleCancelled(uint256 indexed raffleId, uint256 amountRaised); // The raffle is closed successfully and the platform receives the fee event FeeTransferredToPlatform( uint256 indexed raffleId, uint256 amountTransferred ); // When the raffle is asked to be cancelled and 30 days have passed, the operator can call a method // to transfer the remaining funds and this event is emitted event RemainingFundsTransferred( uint256 indexed raffleId, uint256 amountInWeis ); // When the raffle is asked to be cancelled and 30 days have not passed yet, the players can call a // method to refund the amount spent on the raffle and this event is emitted event Refund( uint256 indexed raffleId, uint256 amountInWeis, address indexed player ); event EarlyCashoutTriggered(uint256 indexed raffleId, uint256 amountRaised); event SetWinnerTriggered(uint256 indexed raffleId, uint256 amountRaised); event StatusChangedInEmergency(uint256 indexed raffleId, uint256 newStatus); // Emitted when an entry is cancelled event EntryCancelled( uint256 indexed raffleId, uint256 amountOfEntriesCanceled, address player ); struct PriceStructure { uint256 id; uint48 numEntries; uint256 price; } mapping(uint256 => PriceStructure) public pricesList; // Every raffle has a funding structure. struct FundingStructure { uint128 minimumFundsInWeis; uint128 desiredFundsInWeis; } mapping(uint256 => FundingStructure) public fundingList; // In order to calculate the winner, in this struct is saved for each bought the data struct EntriesBought { uint48 currentEntriesLength; // current amount of entries bought in the raffle address player; // wallet address of the player } // every raffle has a sorted array of EntriesBought. Each element is created when calling // either buyEntry or giveBatchEntriesForFree mapping(uint256 => EntriesBought[]) public entriesList; // Main raffle data struct struct RaffleStruct { uint48 platformPercentage; // percentage of the funds raised that goes to the platform uint256 prizeNumber; // number (can be a percentage, an id, an amount, etc. depending on the competition) address winner; // address of thed winner of the raffle. Address(0) if no winner yet address seller; // address of the seller of the NFT uint256 randomNumber; // normalized (0-Entries array size) random number generated by the VRF } // The main structure is an array of raffles RaffleStruct[] public raffles; struct EntryInfoStruct { STATUS status; // status of the raffle. Can be created, accepted, ended, etc ENTRY_TYPE entryType; uint48 entriesLength; // to easy frontend, the length of the entries array is saved here uint128 amountRaised; // funds raised so far in wei } // The main structure is an array of raffles EntryInfoStruct[] public rafflesEntryInfo; // All the different status a rafVRFCoordinatorfle can have enum STATUS { CREATED, // the operator creates the raffle ACCEPTED, // the seller stakes the nft for the raffle EARLY_CASHOUT, // the seller wants to cashout early CANCELLED, // the operator cancels the raffle and transfer the remaining funds after 30 days passes CLOSING_REQUESTED, // the operator sets a winner ENDED, // the raffle is finished, and NFT and funds were transferred CANCEL_REQUESTED // operator asks to cancel the raffle. Players has 30 days to ask for a refund } enum ENTRY_TYPE { ONLY_DIRECTLY, ONLY_EXTERNAL_CONTRACT, MIXED } // The operator role is operated by a backend application bytes32 public constant OPERATOR_ROLE = keccak256("OPERATOR"); // requested by Hamburger. Role for the buy method of the hamburger (only that contract) bytes32 public constant MINTERCONTRACT_ROLE = keccak256("MINTERCONTRACT"); // address of the wallet controlled by the platform that will receive the platform fee address payable public destinationWallet = payable(0x52a032cF59eA274f9D745f29b6D514fe95Ba192D); constructor( address _vrfCoordinator, address _linkToken, bytes32 _keyHash, bool _mainetFee ) VRFConsumerBase( _vrfCoordinator, // VRF Coordinator _linkToken // LINK Token ) { _setupRole(OPERATOR_ROLE, 0x13503B622abC0bD30A7e9687057DF6E8c42Fb928); _setupRole(DEFAULT_ADMIN_ROLE, msg.sender); keyHash = _keyHash; if (_mainetFee == true) fee = 2 * 10 ** 18; // in mainnet, the fee must be 2 LINK else fee = 0.1 * 10 ** 18; // 0.1 LINK In Rinkeby and Goerli } function callVRFAndGetRequestId() internal returns (bytes32 requestId) { require( LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet" ); bytes32 result = requestRandomness(keyHash, fee); return result; } /// @dev this is the method that will be called by the smart contract to get a random number /// @param _id Id of the raffle /// @param _entriesSize length of the entries array of that raffle /// @param _requestId id generated by Chainlink function getRandomNumber( uint256 _id, uint256 _entriesSize, bytes32 _requestId ) internal { chainlinkRaffleInfo[_requestId] = RaffleInfo({ id: _id, size: _entriesSize }); } /// @dev Callback function used by VRF Coordinator. Is called by chainlink /// the random number generated is normalized to the size of the entries array, and an event is /// generated, that will be listened by the platform backend to be checked if corresponds to a /// member of the MW community, and if true will call transferNFTAndFunds /// @param requestId id generated previously (on method getRandomNumber by chainlink) /// @param randomness random number (huge) generated by chainlink function fulfillRandomness( bytes32 requestId, uint256 randomness ) internal override { // randomness is the actual random number. Now extract from the aux map the original param id of the call RaffleInfo memory raffleInfo = chainlinkRaffleInfo[requestId]; // save the random number on the map with the original id as key uint256 normalizedRandomNumber = (randomness % raffleInfo.size) + 1; RandomResult memory result = RandomResult({ randomNumber: randomness, nomalizedRandomNumber: normalizedRandomNumber }); requests[raffleInfo.id] = result; // send the event with the original id and the random number emit RandomNumberCreated( raffleInfo.id, randomness, normalizedRandomNumber ); transferPrizesAndFunds(raffleInfo.id, normalizedRandomNumber); } ////////////////////////////////////////////// /// @param _desiredFundsInWeis the amount the seller would like to get from the raffle /// @param _collateralAddress The address of the NFT of the raffle /// @param _collateralId The id of the NFT (ERC721) /// @param _minimumFundsInWeis The mininum amount required for the raffle to set a winner /// @param _prices Array of prices and amount of entries the customer could purchase // /// @param _commissionInBasicPoints commission for the platform, in basic points /// @notice Creates a raffle /// @dev creates a raffle struct and push it to the raffles array. Some data is stored in the funding data structure /// sends an event when finished /// @return raffleId function createRaffle( uint128 _desiredFundsInWeis, uint256 _prizeNumber, uint128 _minimumFundsInWeis, PriceStructure[] calldata _prices, uint48 _commissionInBasicPoints, ENTRY_TYPE _entryType ) external onlyRole(OPERATOR_ROLE) returns (uint256) { require(_commissionInBasicPoints <= 5000, "commission too high"); RaffleStruct memory raffle = RaffleStruct({ prizeNumber: _prizeNumber, winner: address(0), randomNumber: 0, seller: address(0), platformPercentage: _commissionInBasicPoints }); raffles.push(raffle); saveEntryInfo(_entryType); uint256 idRaffle = raffles.length - 1; require(_prices.length > 0, "No prices"); for (uint256 i = 0; i < _prices.length; i++) { require(_prices[i].numEntries > 0, "numEntries is 0"); PriceStructure memory p = PriceStructure({ id: idRaffle, numEntries: _prices[i].numEntries, price: _prices[i].price }); pricesList[_prices[i].id] = p; } fundingList[idRaffle] = FundingStructure({ minimumFundsInWeis: _minimumFundsInWeis, desiredFundsInWeis: _desiredFundsInWeis }); emit RaffleCreated(idRaffle, _prizeNumber); // Initialize the entries list array, by adding a player and removing it EntriesBought memory entryBought = EntriesBought({ player: msg.sender, currentEntriesLength: uint48(1) }); entriesList[idRaffle].push(entryBought); delete entriesList[idRaffle][0]; return idRaffle; } function saveEntryInfo(ENTRY_TYPE _entryType) internal { EntryInfoStruct memory entryInfo = EntryInfoStruct({ status: STATUS.CREATED, amountRaised: 0, entriesLength: 0, entryType: _entryType }); rafflesEntryInfo.push(entryInfo); } /// @param _raffleId Id of the raffle function stakeETH(uint256 _raffleId) external payable { EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; RaffleStruct storage raffle = raffles[_raffleId]; // Check if the raffle is already created require(entryInfo.status == STATUS.CREATED, "Raffle not CREATED"); // check the amount staked is the correct require(raffle.prizeNumber == msg.value, "Prize not staked"); entryInfo.status = STATUS.ACCEPTED; raffle.seller = msg.sender; emit RaffleStarted(_raffleId, msg.sender); } /// @dev callable by players. Depending on the number of entries assigned to the price structure the player buys (_id parameter) /// one or more entries will be assigned to the player. /// Also it is checked the maximum number of entries per user is not reached /// As the method is payable, in msg.value there will be the amount paid by the user /// @notice If the operator set requiredNFTs when creating the raffle, only the owners of nft on that collection can make a call to this method. This will be /// used for special raffles /// @param _raffleId: id of the raffle /// @param _id: id of the price structure function buyEntry( uint256 _raffleId, uint256 _id ) external payable /*nonReentrant*/ { EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; if (entryInfo.status != STATUS.ACCEPTED) revert EntryNotAllowed("Not in ACCEPTED"); // Not callable if the contract is only using hamburgers (150 gas) if (entryInfo.entryType == ENTRY_TYPE.ONLY_EXTERNAL_CONTRACT) revert EntryNotAllowed("Entry type not allowed"); // Price checks if (_id == 0) revert EntryNotAllowed("howMany is 0"); PriceStructure memory priceStruct = pricesList[_id]; if (priceStruct.id != _raffleId) revert EntryNotAllowed("Id not in raffleId"); uint48 numEntries = priceStruct.numEntries; if (numEntries == 0) revert EntryNotAllowed("Id not supported"); if (msg.value != priceStruct.price) revert EntryNotAllowed("msg.value must be equal to the price"); // save the entries onchain uint48 entriesLength = entryInfo.entriesLength; EntriesBought memory entryBought = EntriesBought({ player: msg.sender, currentEntriesLength: uint48(entriesLength + numEntries) }); entriesList[_raffleId].push(entryBought); // update raffle variables entryInfo.amountRaised += uint128(msg.value); entryInfo.entriesLength = entriesLength + numEntries; emit EntrySold(_raffleId, msg.sender, entryInfo.entriesLength, _id); } // The operator can add free entries to the raffle /// @param _raffleId Id of the raffle /// @param _freePlayers array of addresses corresponding to the wallet of the users that won a free entrie /// @dev only operator can make this call. Assigns a single entry per user, except if that user already reached the max limit of entries per user function giveBatchEntriesForFree( uint256 _raffleId, address[] memory _freePlayers ) external onlyRole(OPERATOR_ROLE) { EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; require( entryInfo.status == STATUS.ACCEPTED, "Raffle is not in accepted" ); uint256 freePlayersLength = _freePlayers.length; uint48 validPlayersCount = 0; for (uint256 i = 0; i < freePlayersLength; i++) { address entry = _freePlayers[i]; // add a new element to the entriesBought array. // as this method only adds 1 entry per call, the amountbought is always 1 EntriesBought memory entryBought = EntriesBought({ player: entry, currentEntriesLength: uint48(entryInfo.entriesLength + i + 1) }); entriesList[_raffleId].push(entryBought); ++validPlayersCount; } entryInfo.entriesLength = entryInfo.entriesLength + validPlayersCount; emit FreeEntry( _raffleId, _freePlayers, freePlayersLength, entryInfo.entriesLength ); } // helper method to get the winner address of a raffle /// @param _raffleId Id of the raffle /// @param _normalizedRandomNumber Generated by chainlink /// @return the wallet that won the raffle /// @dev Uses a binary search on the sorted array to retreive the winner /// but if the winner candidate is blacklisted, loop through the left looking for /// a candidate not blacklisted function getWinnerAddressFromRandom( uint256 _raffleId, uint256 _normalizedRandomNumber ) public view returns (address) { uint256 position = findUpperBound( entriesList[_raffleId], _normalizedRandomNumber ); address candidate = entriesList[_raffleId][position].player; // general case if (candidate != address(0)) return candidate; // special case. The user is blacklisted, so try next on the left until find a non-blacklisted else { bool ended = false; uint256 i = position; while ( ended == false && entriesList[_raffleId][i].player == address(0) ) { if (i == 0) i = entriesList[_raffleId].length - 1; else i = i - 1; // we came to the beginning without finding a non blacklisted player if (i == position) ended == true; } require(!ended, "All users blacklisted"); return entriesList[_raffleId][i].player; } } /// @param array sorted array of EntriesBought. CurrentEntriesLength is the numeric field used to sort /// @param element uint256 to find. Goes from 1 to entriesLength /// @dev based on openzeppelin code (v4.0), modified to use an array of EntriesBought /// Searches a sorted array and returns the first index that contains a value greater or equal to element. /// If no such index exists (i.e. all values in the array are strictly less than element), the array length is returned. Time complexity O(log n). /// array is expected to be sorted in ascending order, and to contain no repeated elements. /// https://docs.openzeppelin.com/contracts/3.x/api/utils#Arrays-findUpperBound-uint256---uint256- function findUpperBound( EntriesBought[] storage array, uint256 element ) internal view returns (uint256) { if (array.length == 0) { return 0; } uint256 low = 0; uint256 high = array.length; while (low < high) { uint256 mid = Math.average(low, high); // Note that mid will always be strictly less than high (i.e. it will be a valid array index) // because Math.average rounds down (it does integer division with truncation). if (array[mid].currentEntriesLength > element) { high = mid; } else { low = mid + 1; } } // At this point `low` is the exclusive upper bound. We will return the inclusive upper bound. if (low > 0 && array[low - 1].currentEntriesLength == element) { return low - 1; } else { return low; } } // The operator can call this method once they receive the event "RandomNumberCreated" // triggered by the VRF v1 consumer contract (RandomNumber.sol) /// @param _raffleId Id of the raffle /// @param _normalizedRandomNumber index of the array that contains the winner of the raffle. Generated by chainlink /// @notice it is the method that sets the winner and transfers funds and nft /// @dev called by Chainlink callback function transferPrizesAndFunds( uint256 _raffleId, uint256 _normalizedRandomNumber ) internal { RaffleStruct storage raffle = raffles[_raffleId]; EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; // Only when the raffle has been asked to be closed and the platform require( entryInfo.status == STATUS.EARLY_CASHOUT || entryInfo.status == STATUS.CLOSING_REQUESTED, "Raffle in wrong status" ); raffle.randomNumber = _normalizedRandomNumber; raffle.winner = getWinnerAddressFromRandom( _raffleId, _normalizedRandomNumber ); entryInfo.status = STATUS.ENDED; // send the ETH to the winner (bool sentPrize, ) = raffle.winner.call{value: raffle.prizeNumber}(""); require(sentPrize, "Failed to send Ether"); uint256 amountForPlatform = (entryInfo.amountRaised * raffle.platformPercentage) / 10000; uint256 amountForSeller = entryInfo.amountRaised - amountForPlatform; // transfer amount (75%) to the seller. (bool sent, ) = raffle.seller.call{value: amountForSeller}(""); require(sent, "Failed to send Ether"); // transfer the amount to the platform (bool sent2, ) = destinationWallet.call{value: amountForPlatform}(""); require(sent2, "Failed send Eth to MW"); emit FeeTransferredToPlatform(_raffleId, amountForPlatform); emit RaffleEnded( _raffleId, raffle.winner, entryInfo.amountRaised, _normalizedRandomNumber ); } function setCashOutActions( uint256 _raffleId ) internal returns (EntryInfoStruct memory) { RaffleStruct memory raffle = raffles[_raffleId]; EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; FundingStructure memory funding = fundingList[_raffleId]; require(raffle.seller == msg.sender, "Not the seller"); // Check if the raffle is already accepted require( entryInfo.status == STATUS.ACCEPTED, "Raffle not in accepted status" ); require( entryInfo.amountRaised >= funding.minimumFundsInWeis, "Not enough funds raised" ); entryInfo.status = STATUS.EARLY_CASHOUT; emit EarlyCashoutTriggered(_raffleId, entryInfo.amountRaised); return entryInfo; } // can be called by the seller at every moment once enough funds has been raised /// @param _raffleId Id of the raffle /// @notice the seller of the nft, if the minimum amount has been reached, can call an early cashout, finishing the raffle /// @dev it triggers Chainlink VRF1 consumer, and generates a random number that is normalized and checked that corresponds to a MW player function earlyCashOut(uint256 _raffleId) external { /* EntryInfoStruct memory raffle = setWinnerActions(_raffleId); bytes32 requestId = callVRFAndGetRequestId(); getRandomNumber(_raffleId, raffle.entriesLength, requestId);*/ } function setWinnerActions( uint256 _raffleId ) internal returns (EntryInfoStruct memory) { EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; // RaffleStruct storage raffle = raffles[_raffleId]; FundingStructure storage funding = fundingList[_raffleId]; // Check if the raffle is already accepted or is called again because early cashout failed require(entryInfo.status == STATUS.ACCEPTED, "Raffle in wrong status"); require( entryInfo.amountRaised >= funding.minimumFundsInWeis, "Not enough funds raised" ); require( funding.desiredFundsInWeis <= entryInfo.amountRaised, "Desired funds not raised" ); entryInfo.status = STATUS.CLOSING_REQUESTED; emit SetWinnerTriggered(_raffleId, entryInfo.amountRaised); return entryInfo; } /// @param _raffleId Id of the raffle /// @notice the operator finish the raffle, if the desired funds has been reached /// @dev it triggers Chainlink VRF1 consumer, and generates a random number that is normalized and checked that corresponds to a MW player function setWinner(uint256 _raffleId) external onlyRole(OPERATOR_ROLE) { EntryInfoStruct memory raffle = setWinnerActions(_raffleId); // this call trigers the VRF v1 process from Chainlink bytes32 requestId = callVRFAndGetRequestId(); getRandomNumber(_raffleId, raffle.entriesLength, requestId); } /// @param _newAddress new address of the platform /// @dev Change the wallet of the platform. The one that will receive the platform fee when the raffle is closed. /// Only the admin can change this function setDestinationAddress( address payable _newAddress ) external onlyRole(DEFAULT_ADMIN_ROLE) { destinationWallet = _newAddress; } /// @param _raffleId Id of the raffle /// @dev The operator can cancel the raffle. The NFT is sent back to the seller /// The raised funds are send to the destination wallet. The buyers will /// be refunded offchain in the metawin wallet function cancelRaffle(uint256 _raffleId) external onlyRole(OPERATOR_ROLE) { RaffleStruct storage raffle = raffles[_raffleId]; EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; // Dont cancel twice, or cancel an already ended raffle require( entryInfo.status != STATUS.ENDED && entryInfo.status != STATUS.CANCELLED && entryInfo.status != STATUS.EARLY_CASHOUT && entryInfo.status != STATUS.CLOSING_REQUESTED && entryInfo.status != STATUS.CANCEL_REQUESTED, "Wrong status" ); // only if the raffle is in accepted status the ETH is staked and could have entries sold if (entryInfo.status == STATUS.ACCEPTED) { // transfer ETH to the owner (bool sentPrize, ) = raffle.seller.call{value: raffle.prizeNumber}( "" ); require(sentPrize, "Failed to send Ether"); } entryInfo.status = STATUS.CANCEL_REQUESTED; emit RaffleCancelled(_raffleId, entryInfo.amountRaised); } /// @param _raffleId Id of the raffle function transferRemainingFunds( uint256 _raffleId ) external onlyRole(OPERATOR_ROLE) { EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; require( entryInfo.status == STATUS.CANCEL_REQUESTED || entryInfo.status == STATUS.CANCELLED, "Wrong status" ); entryInfo.status = STATUS.CANCELLED; (bool sent, ) = destinationWallet.call{value: entryInfo.amountRaised}( "" ); require(sent, "Fail send Eth to MW"); emit RemainingFundsTransferred(_raffleId, entryInfo.amountRaised); entryInfo.amountRaised = 0; } /// @param _raffleId Id of the raffle /// @return array of entries bougth of that particular raffle function getEntriesBought( uint256 _raffleId ) external view returns (EntriesBought[] memory) { return entriesList[_raffleId]; } /// @dev for different reasons player entries should be void /// this has a cost in gas, but this makes cheaper in gas the callback from chainlink /// This method has to be called for every raffle of the blacklisted player /// @param _raffleId Id of the raffle /// @param entriesToCancel array that contains the index of the entries to cancel. 0 based /// @param _player player who owns the entry to be voided function cancelEntry( uint256 _raffleId, uint256[] calldata entriesToCancel, address _player ) external onlyRole(OPERATOR_ROLE) { uint256 totalEntriesBoughtCancelled = 0; for (uint256 i = 0; i < entriesToCancel.length; i++) { EntriesBought storage entry = entriesList[_raffleId][ entriesToCancel[i] + 1 ]; require(entry.player == _player, "Entry did not belong to player"); entry.player = address(0); uint256 previousTotalEntriesLength; if (entriesToCancel[i] == 0) previousTotalEntriesLength = 0; else previousTotalEntriesLength = entriesList[_raffleId][ entriesToCancel[i] /* - 1*/ ].currentEntriesLength; totalEntriesBoughtCancelled += entry.currentEntriesLength - previousTotalEntriesLength; } emit EntryCancelled(_raffleId, totalEntriesBoughtCancelled, _player); } // Requested by Valerio Di Napoli. /// @param _raffleId id of the raffle /// @param _amountOfEntries amount of entries. Must be lower than maxEntriesPerUser /// @param _player The address of the player /// @notice Called by other contract created by Valerio, that minted an NFT and after that call this method /// @dev add entries but they are free so no payable function createFreeEntriesFromExternalContract( uint256 _raffleId, uint48 _amountOfEntries, address _player ) external onlyRole(MINTERCONTRACT_ROLE) { // if can buy run this code. EntryInfoStruct storage entryInfo = rafflesEntryInfo[_raffleId]; require( entryInfo.entryType == ENTRY_TYPE.ONLY_EXTERNAL_CONTRACT || entryInfo.entryType == ENTRY_TYPE.MIXED, "Entry type not allowed" ); EntriesBought memory entryBought = EntriesBought({ player: _player, currentEntriesLength: entryInfo.entriesLength + _amountOfEntries }); entriesList[_raffleId].push(entryBought); // update the field entriesLength. entryInfo.entriesLength += _amountOfEntries; address[] memory players = new address[](1); players[0] = _player; emit FreeEntry( _raffleId, players, _amountOfEntries, entryInfo.entriesLength ); } function getRafflesEntryInfo( uint256 _raffleId ) public view returns (EntryInfoStruct memory) { return rafflesEntryInfo[_raffleId]; } function playerIsBlacklisted(address _player) external pure returns (bool) { // return blackListManager.isBlackListed(_player); return false; } function raffleNotInAcceptedState( uint256 _raffleId ) external view returns (bool) { EntryInfoStruct memory entryInfo = rafflesEntryInfo[_raffleId]; return (entryInfo.status != STATUS.ACCEPTED); } function playerIsSeller( address _player, uint256 _raffleId ) external view returns (bool) { RaffleStruct memory raffle = raffles[_raffleId]; return (raffle.seller == _player); } function playerReachedMaxEntries( address _player, uint256 _raffleId, uint256 _amountOfEntries ) external pure returns (bool) { return false; } /* Requested by Valerio Di Napoli. @param _player The address of the player @param _raffleId id of the raffle @param _colection Address of the required collection, if any @param _tokenIdUsed Id of the token of the required collection the player says he has and want to use in the raffle @returns bool if the player can buy or not, and string with the cause of the rejection. "" if can buy @notice Method that returns if the user can or cannot buy entries because the player owns an nft in the case or required collections. */ function playerHasRequiredNFTs( address _player, uint256 _raffleId, address _collection, uint256 _tokenIdUsed ) external pure returns (bool canBuy, string memory cause) { return (true, ""); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (utils/math/Math.sol) pragma solidity ^0.8.0; /** * @dev Standard math utilities missing in the Solidity language. */ library Math { enum Rounding { Down, // Toward negative infinity Up, // Toward infinity Zero // Toward zero } /** * @dev Returns the largest of two numbers. */ function max(uint256 a, uint256 b) internal pure returns (uint256) { return a >= b ? a : b; } /** * @dev Returns the smallest of two numbers. */ function min(uint256 a, uint256 b) internal pure returns (uint256) { return a < b ? a : b; } /** * @dev Returns the average of two numbers. The result is rounded towards * zero. */ function average(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b) / 2 can overflow. return (a & b) + (a ^ b) / 2; } /** * @dev Returns the ceiling of the division of two numbers. * * This differs from standard division with `/` in that it rounds up instead * of rounding down. */ function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) { // (a + b - 1) / b can overflow on addition, so we distribute. return a == 0 ? 0 : (a - 1) / b + 1; } /** * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0 * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) * with further edits by Uniswap Labs also under MIT license. */ function mulDiv( uint256 x, uint256 y, uint256 denominator ) internal pure returns (uint256 result) { unchecked { // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256 // variables such that product = prod1 * 2^256 + prod0. uint256 prod0; // Least significant 256 bits of the product uint256 prod1; // Most significant 256 bits of the product assembly { let mm := mulmod(x, y, not(0)) prod0 := mul(x, y) prod1 := sub(sub(mm, prod0), lt(mm, prod0)) } // Handle non-overflow cases, 256 by 256 division. if (prod1 == 0) { return prod0 / denominator; } // Make sure the result is less than 2^256. Also prevents denominator == 0. require(denominator > prod1); /////////////////////////////////////////////// // 512 by 256 division. /////////////////////////////////////////////// // Make division exact by subtracting the remainder from [prod1 prod0]. uint256 remainder; assembly { // Compute remainder using mulmod. remainder := mulmod(x, y, denominator) // Subtract 256 bit number from 512 bit number. prod1 := sub(prod1, gt(remainder, prod0)) prod0 := sub(prod0, remainder) } // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1. // See https://cs.stackexchange.com/q/138556/92363. // Does not overflow because the denominator cannot be zero at this stage in the function. uint256 twos = denominator & (~denominator + 1); assembly { // Divide denominator by twos. denominator := div(denominator, twos) // Divide [prod1 prod0] by twos. prod0 := div(prod0, twos) // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one. twos := add(div(sub(0, twos), twos), 1) } // Shift in bits from prod1 into prod0. prod0 |= prod1 * twos; // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for // four bits. That is, denominator * inv = 1 mod 2^4. uint256 inverse = (3 * denominator) ^ 2; // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works // in modular arithmetic, doubling the correct bits in each step. inverse *= 2 - denominator * inverse; // inverse mod 2^8 inverse *= 2 - denominator * inverse; // inverse mod 2^16 inverse *= 2 - denominator * inverse; // inverse mod 2^32 inverse *= 2 - denominator * inverse; // inverse mod 2^64 inverse *= 2 - denominator * inverse; // inverse mod 2^128 inverse *= 2 - denominator * inverse; // inverse mod 2^256 // Because the division is now exact we can divide by multiplying with the modular inverse of denominator. // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1 // is no longer required. result = prod0 * inverse; return result; } } /** * @notice Calculates x * y / denominator with full precision, following the selected rounding direction. */ function mulDiv( uint256 x, uint256 y, uint256 denominator, Rounding rounding ) internal pure returns (uint256) { uint256 result = mulDiv(x, y, denominator); if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) { result += 1; } return result; } /** * @dev Returns the square root of a number. It the number is not a perfect square, the value is rounded down. * * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11). */ function sqrt(uint256 a) internal pure returns (uint256) { if (a == 0) { return 0; } // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target. // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have // `msb(a) <= a < 2*msb(a)`. // We also know that `k`, the position of the most significant bit, is such that `msb(a) = 2**k`. // This gives `2**k < a <= 2**(k+1)` → `2**(k/2) <= sqrt(a) < 2 ** (k/2+1)`. // Using an algorithm similar to the msb conmputation, we are able to compute `result = 2**(k/2)` which is a // good first aproximation of `sqrt(a)` with at least 1 correct bit. uint256 result = 1; uint256 x = a; if (x >> 128 > 0) { x >>= 128; result <<= 64; } if (x >> 64 > 0) { x >>= 64; result <<= 32; } if (x >> 32 > 0) { x >>= 32; result <<= 16; } if (x >> 16 > 0) { x >>= 16; result <<= 8; } if (x >> 8 > 0) { x >>= 8; result <<= 4; } if (x >> 4 > 0) { x >>= 4; result <<= 2; } if (x >> 2 > 0) { result <<= 1; } // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128, // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision // into the expected uint128 result. unchecked { result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; result = (result + a / result) >> 1; return min(result, a / result); } } /** * @notice Calculates sqrt(a), following the selected rounding direction. */ function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) { uint256 result = sqrt(a); if (rounding == Rounding.Up && result * result < a) { result += 1; } return result; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol) pragma solidity ^0.8.0; /** * @dev Interface of the ERC165 standard, as defined in the * https://eips.ethereum.org/EIPS/eip-165[EIP]. * * Implementers can declare support of contract interfaces, which can then be * queried by others ({ERC165Checker}). * * For an implementation, see {ERC165}. */ interface IERC165 { /** * @dev Returns true if this contract implements the interface defined by * `interfaceId`. See the corresponding * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section] * to learn more about how these ids are created. * * This function call must use less than 30 000 gas. */ function supportsInterface(bytes4 interfaceId) external view returns (bool); }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (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 (last updated v4.7.0) (utils/Strings.sol) pragma solidity ^0.8.0; /** * @dev String operations. */ library Strings { bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef"; uint8 private constant _ADDRESS_LENGTH = 20; /** * @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); } /** * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation. */ function toHexString(address addr) internal pure returns (string memory) { return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH); } }
// 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 (access/IAccessControl.sol) pragma solidity ^0.8.0; /** * @dev External interface of AccessControl declared to support ERC165 detection. */ interface IAccessControl { /** * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole` * * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite * {RoleAdminChanged} not being emitted signaling this. * * _Available since v3.1._ */ event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole); /** * @dev Emitted when `account` is granted `role`. * * `sender` is the account that originated the contract call, an admin role * bearer except when using {AccessControl-_setupRole}. */ event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Emitted when `account` is revoked `role`. * * `sender` is the account that originated the contract call: * - if using `revokeRole`, it is the admin role bearer * - if using `renounceRole`, it is the role bearer (i.e. `account`) */ event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender); /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) external view returns (bool); /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {AccessControl-_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) external view returns (bytes32); /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function grantRole(bytes32 role, address account) external; /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. */ function revokeRole(bytes32 role, address account) external; /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been granted `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. */ function renounceRole(bytes32 role, address account) external; }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol) pragma solidity ^0.8.0; import "./IAccessControl.sol"; import "../utils/Context.sol"; import "../utils/Strings.sol"; import "../utils/introspection/ERC165.sol"; /** * @dev Contract module that allows children to implement role-based access * control mechanisms. This is a lightweight version that doesn't allow enumerating role * members except through off-chain means by accessing the contract event logs. Some * applications may benefit from on-chain enumerability, for those cases see * {AccessControlEnumerable}. * * Roles are referred to by their `bytes32` identifier. These should be exposed * in the external API and be unique. The best way to achieve this is by * using `public constant` hash digests: * * ``` * bytes32 public constant MY_ROLE = keccak256("MY_ROLE"); * ``` * * Roles can be used to represent a set of permissions. To restrict access to a * function call, use {hasRole}: * * ``` * function foo() public { * require(hasRole(MY_ROLE, msg.sender)); * ... * } * ``` * * Roles can be granted and revoked dynamically via the {grantRole} and * {revokeRole} functions. Each role has an associated admin role, and only * accounts that have a role's admin role can call {grantRole} and {revokeRole}. * * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means * that only accounts with this role will be able to grant or revoke other * roles. More complex role relationships can be created by using * {_setRoleAdmin}. * * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to * grant and revoke this role. Extra precautions should be taken to secure * accounts that have been granted it. */ abstract contract AccessControl is Context, IAccessControl, ERC165 { struct RoleData { mapping(address => bool) members; bytes32 adminRole; } mapping(bytes32 => RoleData) private _roles; bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00; /** * @dev Modifier that checks that an account has a specific role. Reverts * with a standardized message including the required role. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ * * _Available since v4.1._ */ modifier onlyRole(bytes32 role) { _checkRole(role); _; } /** * @dev See {IERC165-supportsInterface}. */ function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) { return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId); } /** * @dev Returns `true` if `account` has been granted `role`. */ function hasRole(bytes32 role, address account) public view virtual override returns (bool) { return _roles[role].members[account]; } /** * @dev Revert with a standard message if `_msgSender()` is missing `role`. * Overriding this function changes the behavior of the {onlyRole} modifier. * * Format of the revert message is described in {_checkRole}. * * _Available since v4.6._ */ function _checkRole(bytes32 role) internal view virtual { _checkRole(role, _msgSender()); } /** * @dev Revert with a standard message if `account` is missing `role`. * * The format of the revert reason is given by the following regular expression: * * /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/ */ function _checkRole(bytes32 role, address account) internal view virtual { if (!hasRole(role, account)) { revert( string( abi.encodePacked( "AccessControl: account ", Strings.toHexString(uint160(account), 20), " is missing role ", Strings.toHexString(uint256(role), 32) ) ) ); } } /** * @dev Returns the admin role that controls `role`. See {grantRole} and * {revokeRole}. * * To change a role's admin, use {_setRoleAdmin}. */ function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) { return _roles[role].adminRole; } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleGranted} event. */ function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _grantRole(role, account); } /** * @dev Revokes `role` from `account`. * * If `account` had been granted `role`, emits a {RoleRevoked} event. * * Requirements: * * - the caller must have ``role``'s admin role. * * May emit a {RoleRevoked} event. */ function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) { _revokeRole(role, account); } /** * @dev Revokes `role` from the calling account. * * Roles are often managed via {grantRole} and {revokeRole}: this function's * purpose is to provide a mechanism for accounts to lose their privileges * if they are compromised (such as when a trusted device is misplaced). * * If the calling account had been revoked `role`, emits a {RoleRevoked} * event. * * Requirements: * * - the caller must be `account`. * * May emit a {RoleRevoked} event. */ function renounceRole(bytes32 role, address account) public virtual override { require(account == _msgSender(), "AccessControl: can only renounce roles for self"); _revokeRole(role, account); } /** * @dev Grants `role` to `account`. * * If `account` had not been already granted `role`, emits a {RoleGranted} * event. Note that unlike {grantRole}, this function doesn't perform any * checks on the calling account. * * May emit a {RoleGranted} event. * * [WARNING] * ==== * This function should only be called from the constructor when setting * up the initial roles for the system. * * Using this function in any other way is effectively circumventing the admin * system imposed by {AccessControl}. * ==== * * NOTE: This function is deprecated in favor of {_grantRole}. */ function _setupRole(bytes32 role, address account) internal virtual { _grantRole(role, account); } /** * @dev Sets `adminRole` as ``role``'s admin role. * * Emits a {RoleAdminChanged} event. */ function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual { bytes32 previousAdminRole = getRoleAdmin(role); _roles[role].adminRole = adminRole; emit RoleAdminChanged(role, previousAdminRole, adminRole); } /** * @dev Grants `role` to `account`. * * Internal function without access restriction. * * May emit a {RoleGranted} event. */ function _grantRole(bytes32 role, address account) internal virtual { if (!hasRole(role, account)) { _roles[role].members[account] = true; emit RoleGranted(role, account, _msgSender()); } } /** * @dev Revokes `role` from `account`. * * Internal function without access restriction. * * May emit a {RoleRevoked} event. */ function _revokeRole(bytes32 role, address account) internal virtual { if (hasRole(role, account)) { _roles[role].members[account] = false; emit RoleRevoked(role, account, _msgSender()); } } }
// SPDX-License-Identifier: MIT 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; contract VRFRequestIDBase { /** * @notice returns the seed which is actually input to the VRF coordinator * * @dev To prevent repetition of VRF output due to repetition of the * @dev user-supplied seed, that seed is combined in a hash with the * @dev user-specific nonce, and the address of the consuming contract. The * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in * @dev the final seed, but the nonce does protect against repetition in * @dev requests which are included in a single block. * * @param _userSeed VRF seed input provided by user * @param _requester Address of the requesting contract * @param _nonce User-specific nonce at the time of the request */ function makeVRFInputSeed( bytes32 _keyHash, uint256 _userSeed, address _requester, uint256 _nonce ) internal pure returns (uint256) { return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce))); } /** * @notice Returns the id for this request * @param _keyHash The serviceAgreement ID to be used for this request * @param _vRFInputSeed The seed to be passed directly to the VRF * @return The id for this request * * @dev Note that _vRFInputSeed is not the seed passed by the consuming * @dev contract, but the one generated by makeVRFInputSeed */ function makeRequestId(bytes32 _keyHash, uint256 _vRFInputSeed) internal pure returns (bytes32) { return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed)); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.0; import "./interfaces/LinkTokenInterface.sol"; import "./VRFRequestIDBase.sol"; /** **************************************************************************** * @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. * ***************************************************************************** * @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, _link) 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), and have told you the minimum LINK * @dev price for VRF service. Make sure your contract has sufficient LINK, and * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you * @dev want to generate randomness from. * * @dev Once the VRFCoordinator has received and validated the oracle's response * @dev to your request, it will call your contract's fulfillRandomness method. * * @dev The randomness argument to fulfillRandomness is the actual random value * @dev generated from your seed. * * @dev The requestId argument is generated from the keyHash and the seed by * @dev makeRequestId(keyHash, seed). If your contract could have concurrent * @dev requests open, you can use the requestId to track which seed is * @dev associated with which randomness. See VRFRequestIDBase.sol for more * @dev details. (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. (Which is critical to making unpredictable randomness! See the * @dev next section.) * * ***************************************************************************** * @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 ultimate input to the VRF is mixed with the block hash of the * @dev block in which the request is made, user-provided seeds have no impact * @dev on its economic security properties. They are only included for API * @dev compatability with previous versions of this contract. * * @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. */ abstract contract VRFConsumerBase is VRFRequestIDBase { /** * @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 VRFConsumerBase 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 randomness the VRF output */ function fulfillRandomness(bytes32 requestId, uint256 randomness) internal virtual; /** * @dev In order to keep backwards compatibility we have kept the user * seed field around. We remove the use of it because given that the blockhash * enters later, it overrides whatever randomness the used seed provides. * Given that it adds no security, and can easily lead to misunderstandings, * we have removed it from usage and can now provide a simpler API. */ uint256 private constant USER_SEED_PLACEHOLDER = 0; /** * @notice requestRandomness initiates a request for VRF output given _seed * * @dev The fulfillRandomness method receives the output, once it's provided * @dev by the Oracle, and verified by the vrfCoordinator. * * @dev The _keyHash must already be registered with the VRFCoordinator, and * @dev the _fee must exceed the fee specified during registration of the * @dev _keyHash. * * @dev The _seed parameter is vestigial, and is kept only for API * @dev compatibility with older versions. It can't *hurt* to mix in some of * @dev your own randomness, here, but it's not necessary because the VRF * @dev oracle will mix the hash of the block containing your request into the * @dev VRF seed it ultimately uses. * * @param _keyHash ID of public key against which randomness is generated * @param _fee The amount of LINK to send with the request * * @return requestId unique ID for this request * * @dev The returned requestId can be used to distinguish responses to * @dev concurrent requests. It is passed as the first argument to * @dev fulfillRandomness. */ function requestRandomness(bytes32 _keyHash, uint256 _fee) internal returns (bytes32 requestId) { LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER)); // This is the seed passed to VRFCoordinator. The oracle will mix this with // the hash of the block containing this request to obtain the seed/input // which is finally passed to the VRF cryptographic machinery. uint256 vRFSeed = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]); // nonces[_keyHash] must stay in sync with // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest). // This provides protection against the user repeating their input seed, // which would result in a predictable/duplicate output, if multiple such // requests appeared in the same block. nonces[_keyHash] = nonces[_keyHash] + 1; return makeRequestId(_keyHash, vRFSeed); } LinkTokenInterface internal immutable LINK; address private immutable vrfCoordinator; // Nonces for each VRF key from which randomness has been requested. // // Must stay in sync with VRFCoordinator[_keyHash][this] mapping(bytes32 => uint256) /* keyHash */ /* nonce */ private nonces; /** * @param _vrfCoordinator address of VRFCoordinator contract * @param _link address of LINK token contract * * @dev https://docs.chain.link/docs/link-token-contracts */ constructor(address _vrfCoordinator, address _link) { vrfCoordinator = _vrfCoordinator; LINK = LinkTokenInterface(_link); } // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF // proof. rawFulfillRandomness then calls fulfillRandomness, after validating // the origin of the call function rawFulfillRandomness(bytes32 requestId, uint256 randomness) external { require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill"); fulfillRandomness(requestId, randomness); } }
{ "remappings": [], "optimizer": { "enabled": true, "runs": 200 }, "evmVersion": "istanbul", "libraries": {}, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } } }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_linkToken","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"bool","name":"_mainetFee","type":"bool"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"string","name":"errorType","type":"string"}],"name":"EntryNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountRaised","type":"uint256"}],"name":"EarlyCashoutTriggered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountOfEntriesCanceled","type":"uint256"},{"indexed":false,"internalType":"address","name":"player","type":"address"}],"name":"EntryCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"currentSize","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceStructureId","type":"uint256"}],"name":"EntrySold","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountTransferred","type":"uint256"}],"name":"FeeTransferredToPlatform","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"address[]","name":"buyer","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"currentSize","type":"uint256"}],"name":"FreeEntry","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountRaised","type":"uint256"}],"name":"RaffleCancelled","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"nftId","type":"uint256"}],"name":"RaffleCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"winner","type":"address"},{"indexed":false,"internalType":"uint256","name":"amountRaised","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"randomNumber","type":"uint256"}],"name":"RaffleEnded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":true,"internalType":"address","name":"seller","type":"address"}],"name":"RaffleStarted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"idFromMetawin","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"randomNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"normalizedRandomNumber","type":"uint256"}],"name":"RandomNumberCreated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountInWeis","type":"uint256"},{"indexed":true,"internalType":"address","name":"player","type":"address"}],"name":"Refund","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountInWeis","type":"uint256"}],"name":"RemainingFundsTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amountRaised","type":"uint256"}],"name":"SetWinnerTriggered","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"raffleId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newStatus","type":"uint256"}],"name":"StatusChangedInEmergency","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTERCONTRACT_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"},{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"buyEntry","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"},{"internalType":"uint256[]","name":"entriesToCancel","type":"uint256[]"},{"internalType":"address","name":"_player","type":"address"}],"name":"cancelEntry","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"cancelRaffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"chainlinkRaffleInfo","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"size","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"},{"internalType":"uint48","name":"_amountOfEntries","type":"uint48"},{"internalType":"address","name":"_player","type":"address"}],"name":"createFreeEntriesFromExternalContract","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint128","name":"_desiredFundsInWeis","type":"uint128"},{"internalType":"uint256","name":"_prizeNumber","type":"uint256"},{"internalType":"uint128","name":"_minimumFundsInWeis","type":"uint128"},{"components":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint48","name":"numEntries","type":"uint48"},{"internalType":"uint256","name":"price","type":"uint256"}],"internalType":"struct ETHFixedLean.PriceStructure[]","name":"_prices","type":"tuple[]"},{"internalType":"uint48","name":"_commissionInBasicPoints","type":"uint48"},{"internalType":"enum ETHFixedLean.ENTRY_TYPE","name":"_entryType","type":"uint8"}],"name":"createRaffle","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"destinationWallet","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"earlyCashOut","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"entriesList","outputs":[{"internalType":"uint48","name":"currentEntriesLength","type":"uint48"},{"internalType":"address","name":"player","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"fundingList","outputs":[{"internalType":"uint128","name":"minimumFundsInWeis","type":"uint128"},{"internalType":"uint128","name":"desiredFundsInWeis","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"getEntriesBought","outputs":[{"components":[{"internalType":"uint48","name":"currentEntriesLength","type":"uint48"},{"internalType":"address","name":"player","type":"address"}],"internalType":"struct ETHFixedLean.EntriesBought[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"getRafflesEntryInfo","outputs":[{"components":[{"internalType":"enum ETHFixedLean.STATUS","name":"status","type":"uint8"},{"internalType":"enum ETHFixedLean.ENTRY_TYPE","name":"entryType","type":"uint8"},{"internalType":"uint48","name":"entriesLength","type":"uint48"},{"internalType":"uint128","name":"amountRaised","type":"uint128"}],"internalType":"struct ETHFixedLean.EntryInfoStruct","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"},{"internalType":"uint256","name":"_normalizedRandomNumber","type":"uint256"}],"name":"getWinnerAddressFromRandom","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"},{"internalType":"address[]","name":"_freePlayers","type":"address[]"}],"name":"giveBatchEntriesForFree","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"},{"internalType":"uint256","name":"_raffleId","type":"uint256"},{"internalType":"address","name":"_collection","type":"address"},{"internalType":"uint256","name":"_tokenIdUsed","type":"uint256"}],"name":"playerHasRequiredNFTs","outputs":[{"internalType":"bool","name":"canBuy","type":"bool"},{"internalType":"string","name":"cause","type":"string"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"}],"name":"playerIsBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"},{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"playerIsSeller","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_player","type":"address"},{"internalType":"uint256","name":"_raffleId","type":"uint256"},{"internalType":"uint256","name":"_amountOfEntries","type":"uint256"}],"name":"playerReachedMaxEntries","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"pricesList","outputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint48","name":"numEntries","type":"uint48"},{"internalType":"uint256","name":"price","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"raffleNotInAcceptedState","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"raffles","outputs":[{"internalType":"uint48","name":"platformPercentage","type":"uint48"},{"internalType":"uint256","name":"prizeNumber","type":"uint256"},{"internalType":"address","name":"winner","type":"address"},{"internalType":"address","name":"seller","type":"address"},{"internalType":"uint256","name":"randomNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"rafflesEntryInfo","outputs":[{"internalType":"enum ETHFixedLean.STATUS","name":"status","type":"uint8"},{"internalType":"enum ETHFixedLean.ENTRY_TYPE","name":"entryType","type":"uint8"},{"internalType":"uint48","name":"entriesLength","type":"uint48"},{"internalType":"uint128","name":"amountRaised","type":"uint128"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"requests","outputs":[{"internalType":"uint256","name":"randomNumber","type":"uint256"},{"internalType":"uint256","name":"nomalizedRandomNumber","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_newAddress","type":"address"}],"name":"setDestinationAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"setWinner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"stakeETH","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_raffleId","type":"uint256"}],"name":"transferRemainingFunds","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c0604052600b80546001600160a01b0319167352a032cf59ea274f9d745f29b6d514fe95ba192d1790553480156200003757600080fd5b50604051620041d7380380620041d78339810160408190526200005a91620001c8565b6001600160601b0319606085811b821660a05284901b16608052620000b47f523a704056dcd17bcf83bed8b68c59416dac1119be77755efe3bde0a64e46e0c7313503b622abc0bd30a7e9687057df6e8c42fb928620000fb565b620000c1600033620000fb565b600282905560018115151415620000e457671bc16d674ec80000600355620000f1565b67016345785d8a00006003555b5050505062000220565b6200010782826200010b565b5050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff1662000107576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620001673390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b80516001600160a01b0381168114620001c357600080fd5b919050565b60008060008060808587031215620001de578384fd5b620001e985620001ab565b9350620001f960208601620001ab565b9250604085015191506060850151801515811462000215578182fd5b939692955090935050565b60805160601c60a05160601c613f7d6200025a600039600081816122070152612eca0152600081816129700152612e9b0152613f7d6000f3fe60806040526004361061021a5760003560e01c806353b7a59b1161012357806393a75d02116100ab578063d649214c1161006f578063d649214c14610789578063ddba6e6b146107a9578063eb99038c1461080f578063f369145514610833578063f5b541a61461085357600080fd5b806393a75d02146106c357806394985ddd146106f0578063a217fddf14610710578063babdf60b14610725578063d547741f1461076957600080fd5b80636ecc20da116100f25780636ecc20da146106085780637c903fc01461061b5780637fa4cacb1461064f57806381d12c581461066f57806391d14854146106a357600080fd5b806353b7a59b146105335780635d4bc0ce1461056b5780635fba3171146105c85780636371ba0d146105e857600080fd5b8063248a9ca3116101a657806336568abe1161017557806336568abe14610478578063365e36581461049857806336734e34146104c55780633a3956c2146104e55780634239a50c1461051557600080fd5b8063248a9ca3146103b15780632a596800146103ef5780632f2ff15d14610438578063317f30591461045857600080fd5b80630b148ff0116101ed5780630b148ff01461031b5780630df716021461033d5780631e6cd3951461035d5780631fe968571461037d578063236854961461039e57600080fd5b8063013805c51461021f57806301ffc9a71461026a578063039be5581461029a578063043a1c9a146102fb575b600080fd5b34801561022b57600080fd5b5061023f61023a36600461375f565b610875565b6040805165ffffffffffff90931683526001600160a01b039091166020830152015b60405180910390f35b34801561027657600080fd5b5061028a610285366004613780565b6108bd565b6040519015158152602001610261565b3480156102a657600080fd5b506102db6102b5366004613718565b6007602052600090815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610261565b34801561030757600080fd5b5061028a610316366004613652565b6108f4565b34801561032757600080fd5b5061033b6103363660046139dd565b61098d565b005b34801561034957600080fd5b5061033b610358366004613718565b610c49565b34801561036957600080fd5b5061028a610378366004613718565b610cbe565b34801561038957600080fd5b5061028a610398366004613636565b50600090565b61033b6103ac36600461375f565b610de9565b3480156103bd57600080fd5b506103e16103cc366004613718565b60009081526020819052604090206001015490565b604051908152602001610261565b3480156103fb57600080fd5b5061042361040a366004613718565b6005602052600090815260409020805460019091015482565b60408051928352602083019190915201610261565b34801561044457600080fd5b5061033b610453366004613730565b6111b4565b34801561046457600080fd5b5061033b610473366004613718565b6111de565b34801561048457600080fd5b5061033b610493366004613730565b6113ca565b3480156104a457600080fd5b506104b86104b3366004613718565b611448565b6040516102619190613bd1565b3480156104d157600080fd5b5061033b6104e036600461387d565b6114d6565b3480156104f157600080fd5b50610505610500366004613718565b61171f565b6040516102619493929190613c4c565b34801561052157600080fd5b5061033b610530366004613718565b50565b34801561053f57600080fd5b50600b54610553906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b34801561057757600080fd5b5061058b610586366004613718565b61176b565b6040805165ffffffffffff909616865260208601949094526001600160a01b0392831693850193909352166060830152608082015260a001610261565b3480156105d457600080fd5b5061033b6105e3366004613718565b6117c2565b3480156105f457600080fd5b506103e16106033660046137a8565b611a61565b61033b610616366004613718565b611f17565b34801561062757600080fd5b506103e17fde5ee446972f4e39ab62c03aa34b2096680a875c3fdb3eb2f947cbb93341c05881565b34801561065b57600080fd5b5061033b61066a366004613636565b612079565b34801561067b57600080fd5b5061042361068a366004613718565b6004602052600090815260409020805460019091015482565b3480156106af57600080fd5b5061028a6106be366004613730565b6120a7565b3480156106cf57600080fd5b506106e36106de366004613718565b6120d0565b6040516102619190613cce565b3480156106fc57600080fd5b5061033b61070b36600461375f565b6121fc565b34801561071c57600080fd5b506103e1600081565b34801561073157600080fd5b5061075b61074036600461367d565b60408051602081019091526000815260019094509492505050565b604051610261929190613c31565b34801561077557600080fd5b5061033b610784366004613730565b61227e565b34801561079557600080fd5b5061033b6107a4366004613950565b6122a3565b3480156107b557600080fd5b506107ed6107c4366004613718565b600660205260009081526040902080546001820154600290920154909165ffffffffffff169083565b6040805193845265ffffffffffff909216602084015290820152606001610261565b34801561081b57600080fd5b5061028a61082a3660046136c4565b60009392505050565b34801561083f57600080fd5b5061055361084e36600461375f565b6124c5565b34801561085f57600080fd5b506103e1600080516020613f2883398151915281565b6008602052816000526040600020818154811061089157600080fd5b60009182526020909120015465ffffffffffff81169250600160301b90046001600160a01b0316905082565b60006001600160e01b03198216637965db0b60e01b14806108ee57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000806009838154811061091857634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805160a0810182526005909302909101805465ffffffffffff16835260018101549383019390935260028301546001600160a01b0390811691830191909152600383015481166060830181905260049093015460809092019190915285161491505092915050565b7fde5ee446972f4e39ab62c03aa34b2096680a875c3fdb3eb2f947cbb93341c0586109b78161266b565b6000600a85815481106109da57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001905060018154610100900460ff166002811115610a1257634e487b7160e01b600052602160045260246000fd5b1480610a46575060028154610100900460ff166002811115610a4457634e487b7160e01b600052602160045260246000fd5b145b610a905760405162461bcd60e51b8152602060048201526016602482015275115b9d1c9e481d1e5c19481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60006040518060400160405280868460000160029054906101000a900465ffffffffffff16610abf9190613d62565b65ffffffffffff90811682526001600160a01b0380881660209384015260008a8152600884526040812080546001810182559082529084902085519101805494860151909216600160301b026001600160d01b03199094169083161792909217909155835491925086918491600291610b4091859162010000900416613d62565b92506101000a81548165ffffffffffff021916908365ffffffffffff1602179055506000600167ffffffffffffffff811115610b8c57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610bb5578160200160208202803683370190505b5090508481600081518110610bda57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0390921660209283029190910190910152825460405188917f4da4f5fab0816c65315b6f5d15f879f96b98661133d7b3787788f291367604fb91610c389185918b9165ffffffffffff620100009091041690613b9f565b60405180910390a250505050505050565b600080516020613f28833981519152610c618161266b565b6000610c6c83612675565b90506000610c7861294c565b9050610cb884836040015165ffffffffffff1683604080518082018252938452602080850193845260009283526005905290209151825551600190910155565b50505050565b600080600a8381548110610ce257634e487b7160e01b600052603260045260246000fd5b60009182526020909120604080516080810190915291018054829060ff166006811115610d1f57634e487b7160e01b600052602160045260246000fd5b6006811115610d3e57634e487b7160e01b600052602160045260246000fd5b81528154602090910190610100900460ff166002811115610d6f57634e487b7160e01b600052602160045260246000fd5b6002811115610d8e57634e487b7160e01b600052602160045260246000fd5b8152905462010000810465ffffffffffff166020830152600160401b90046001600160801b03166040909101529050600181516006811115610de057634e487b7160e01b600052602160045260246000fd5b14159392505050565b6000600a8381548110610e0c57634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506001815460ff166006811115610e3f57634e487b7160e01b600052602160045260246000fd5b14610e7f5760405163efeb42cf60e01b815260206004820152600f60248201526e139bdd081a5b881050d0d154151151608a1b6044820152606401610a87565b60018154610100900460ff166002811115610eaa57634e487b7160e01b600052602160045260246000fd5b1415610ef25760405163efeb42cf60e01b8152602060048201526016602482015275115b9d1c9e481d1e5c19481b9bdd08185b1b1bddd95960521b6044820152606401610a87565b81610f2f5760405163efeb42cf60e01b815260206004820152600c60248201526b0686f774d616e7920697320360a41b6044820152606401610a87565b60008281526006602090815260409182902082516060810184528154808252600183015465ffffffffffff1693820193909352600290910154928101929092528414610fb35760405163efeb42cf60e01b81526020600482015260126024820152711259081b9bdd081a5b881c9859999b19525960721b6044820152606401610a87565b602081015165ffffffffffff81166110015760405163efeb42cf60e01b815260206004820152601060248201526f1259081b9bdd081cdd5c1c1bdc9d195960821b6044820152606401610a87565b816040015134146110615760405163efeb42cf60e01b8152602060048201526024808201527f6d73672e76616c7565206d75737420626520657175616c20746f2074686520706044820152637269636560e01b6064820152608401610a87565b8254604080518082019091526201000090910465ffffffffffff16906000908061108b8585613d62565b65ffffffffffff90811682523360209283015260008a8152600880845260408220805460018101825590835291849020855192018054948601516001600160a01b0316600160301b026001600160d01b03199095169290931691909117929092179055865491925034918791906111149084906001600160801b03600160401b90910416613d1f565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555082826111449190613d62565b855467ffffffffffff000019166201000065ffffffffffff9283168102919091178088556040805192909104909216815260208101889052339189917fd746af8dc82f9bed98cea0fe0264eb1c3d2e5f7bcc77fc5efb429c79df407887910160405180910390a350505050505050565b6000828152602081905260409020600101546111cf8161266b565b6111d98383612a5c565b505050565b600080516020613f288339815191526111f68161266b565b6000600a838154811061121957634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506006815460ff16600681111561124c57634e487b7160e01b600052602160045260246000fd5b148061127b57506003815460ff16600681111561127957634e487b7160e01b600052602160045260246000fd5b145b6112b65760405162461bcd60e51b815260206004820152600c60248201526b57726f6e672073746174757360a01b6044820152606401610a87565b805460ff1916600317808255600b546040516000926001600160a01b03909216916001600160801b03600160401b90910416908381818185875af1925050503d8060008114611321576040519150601f19603f3d011682016040523d82523d6000602084013e611326565b606091505b505090508061136d5760405162461bcd60e51b81526020600482015260136024820152724661696c2073656e642045746820746f204d5760681b6044820152606401610a87565b8154604051600160401b9091046001600160801b0316815284907fcdef6558dae40f2699846eedf449462daab85b1224ad7f077569ba91aaa949259060200160405180910390a2508054600160401b600160c01b03191690555050565b6001600160a01b038116331461143a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610a87565b6114448282612ae0565b5050565b606060086000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156114cb576000848152602090819020604080518082019091529084015465ffffffffffff81168252600160301b90046001600160a01b03168183015282526001909201910161147d565b505050509050919050565b600080516020613f288339815191526114ee8161266b565b6000600a848154811061151157634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506001815460ff16600681111561154457634e487b7160e01b600052602160045260246000fd5b146115915760405162461bcd60e51b815260206004820152601960248201527f526166666c65206973206e6f7420696e206163636570746564000000000000006044820152606401610a87565b82516000805b828110156116935760008682815181106115c157634e487b7160e01b600052603260045260246000fd5b6020026020010151905060006040518060400160405280848860000160029054906101000a900465ffffffffffff1665ffffffffffff166116029190613d4a565b61160d906001613d4a565b65ffffffffffff90811682526001600160a01b0380861660209384015260008d8152600884526040812080546001810182559082529084902085519101805494860151909216600160301b026001600160d01b0319909416921691909117919091179055905061167c84613e80565b93505050808061168b90613e65565b915050611597565b5082546116af90829062010000900465ffffffffffff16613d62565b835467ffffffffffff000019166201000065ffffffffffff92831681029190911780865560405189937f4da4f5fab0816c65315b6f5d15f879f96b98661133d7b3787788f291367604fb9361170f938b9389939290910490911690613b6e565b60405180910390a2505050505050565b600a818154811061172f57600080fd5b60009182526020909120015460ff80821692506101008204169062010000810465ffffffffffff1690600160401b90046001600160801b031684565b6009818154811061177b57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015465ffffffffffff909316945090926001600160a01b039182169291169085565b600080516020613f288339815191526117da8161266b565b6000600983815481106117fd57634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020190506000600a848154811061183057634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506005815460ff16600681111561186357634e487b7160e01b600052602160045260246000fd5b1415801561189557506003815460ff16600681111561189257634e487b7160e01b600052602160045260246000fd5b14155b80156118c557506002815460ff1660068111156118c257634e487b7160e01b600052602160045260246000fd5b14155b80156118f557506004815460ff1660068111156118f257634e487b7160e01b600052602160045260246000fd5b14155b801561192557506006815460ff16600681111561192257634e487b7160e01b600052602160045260246000fd5b14155b6119605760405162461bcd60e51b815260206004820152600c60248201526b57726f6e672073746174757360a01b6044820152606401610a87565b6001815460ff16600681111561198657634e487b7160e01b600052602160045260246000fd5b1415611a0757600382015460018301546040516000926001600160a01b031691908381818185875af1925050503d80600081146119df576040519150601f19603f3d011682016040523d82523d6000602084013e6119e4565b606091505b5050905080611a055760405162461bcd60e51b8152600401610a8790613ca0565b505b805460ff19166006178082556040516001600160801b03600160401b90920491909116815284907fd512a34b0f0618078770fcd85d974df1ab46a7882e8b3d45aa91764f4961aed29060200160405180910390a250505050565b6000600080516020613f28833981519152611a7b8161266b565b6113888465ffffffffffff161115611acb5760405162461bcd60e51b81526020600482015260136024820152720c6dedadad2e6e6d2dedc40e8dede40d0d2ced606b1b6044820152606401610a87565b6040805160a08101825265ffffffffffff8681168252602082018b81526000938301848152606084018581526080850186815260098054600181018255975285517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af6005909802978801805465ffffffffffff1916919096161790945591517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b0860155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b1850180546001600160a01b03199081166001600160a01b039384161790915591517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b2860180549093169116179055517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b390920191909155611c1084612b45565b600954600090611c2290600190613e0b565b905086611c5d5760405162461bcd60e51b81526020600482015260096024820152684e6f2070726963657360b81b6044820152606401610a87565b60005b87811015611df6576000898983818110611c8a57634e487b7160e01b600052603260045260246000fd5b9050606002016020016020810190611ca29190613a1c565b65ffffffffffff1611611ce95760405162461bcd60e51b815260206004820152600f60248201526e06e756d456e7472696573206973203608c1b6044820152606401610a87565b600060405180606001604052808481526020018b8b85818110611d1c57634e487b7160e01b600052603260045260246000fd5b9050606002016020016020810190611d349190613a1c565b65ffffffffffff1681526020018b8b85818110611d6157634e487b7160e01b600052603260045260246000fd5b90506060020160400135815250905080600660008c8c86818110611d9557634e487b7160e01b600052603260045260246000fd5b60600291909101358252506020808201929092526040908101600020835181559183015160018301805465ffffffffffff191665ffffffffffff90921691909117905591909101516002909101555080611dee81613e65565b915050611c60565b506040805180820182526001600160801b03808c1682528d8116602080840191825260008681526007909152848120935191518316600160801b02919092161790915590518b9183917ff6f5afeb49bc62176d1efaa06a1753999cc29bf378f1004ea916f37f41d7638a9190a360408051808201825260018082523360208084019182526000868152600882529485208054938401815580865290852084519301805492516001600160a01b0316600160301b026001600160d01b031990931665ffffffffffff949094169390931791909117909155838352805491929091611eef57634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160d01b0319169055509a9950505050505050505050565b6000600a8281548110611f3a57634e487b7160e01b600052603260045260246000fd5b906000526020600020019050600060098381548110611f6957634e487b7160e01b600052603260045260246000fd5b6000918252602082206005909102019150825460ff166006811115611f9e57634e487b7160e01b600052602160045260246000fd5b14611fe05760405162461bcd60e51b8152602060048201526012602482015271149859999b19481b9bdd0810d4915055115160721b6044820152606401610a87565b348160010154146120265760405162461bcd60e51b815260206004820152601060248201526f141c9a5e99481b9bdd081cdd185ad95960821b6044820152606401610a87565b815460ff19166001178255600381018054336001600160a01b0319909116811790915560405184907f8bb509eedfd1c4847b0a8a2b4493cf2ebb9970dc367e477cd2a8523e212dc1db90600090a3505050565b60006120848161266b565b50600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6120fc604080516080810190915280600081526020016000815260006020820181905260409091015290565b600a828154811061211d57634e487b7160e01b600052603260045260246000fd5b60009182526020909120604080516080810190915291018054829060ff16600681111561215a57634e487b7160e01b600052602160045260246000fd5b600681111561217957634e487b7160e01b600052602160045260246000fd5b81528154602090910190610100900460ff1660028111156121aa57634e487b7160e01b600052602160045260246000fd5b60028111156121c957634e487b7160e01b600052602160045260246000fd5b8152905462010000810465ffffffffffff166020830152600160401b90046001600160801b031660409091015292915050565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146122745760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610a87565b6114448282612c85565b6000828152602081905260409020600101546122998161266b565b6111d98383612ae0565b600080516020613f288339815191526122bb8161266b565b6000805b848110156124845760008781526008602052604081208787848181106122f557634e487b7160e01b600052603260045260246000fd5b9050602002013560016123089190613d4a565b8154811061232657634e487b7160e01b600052603260045260246000fd5b600091825260209091200180549091506001600160a01b03868116600160301b90920416146123975760405162461bcd60e51b815260206004820152601e60248201527f456e74727920646964206e6f742062656c6f6e6720746f20706c6179657200006044820152606401610a87565b80546601000000000000600160d01b031916815560008787848181106123cd57634e487b7160e01b600052603260045260246000fd5b90506020020135600014156123e45750600061244e565b600089815260086020526040902088888581811061241257634e487b7160e01b600052603260045260246000fd5b905060200201358154811061243757634e487b7160e01b600052603260045260246000fd5b60009182526020909120015465ffffffffffff1690505b815461246390829065ffffffffffff16613e0b565b61246d9085613d4a565b93505050808061247c90613e65565b9150506122bf565b50604080518281526001600160a01b038516602082015287917f2cca80c1af5abb202a642a502875436822768d733462843a7c3a902b0fad99d0910161170f565b600082815260086020526040812081906124df9084612d42565b6000858152600860205260408120805492935090918390811061251257634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160301b90046001600160a01b03169050801561253f5791506108ee9050565b6000825b811580156125985750600087815260086020526040812080548390811061257a57634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160301b90046001600160a01b0316145b156125cf57806125c4576000878152600860205260409020546125bd90600190613e0b565b9050612543565b6125bd600182613e0b565b81156126155760405162461bcd60e51b8152602060048201526015602482015274105b1b081d5cd95c9cc8189b1858dadb1a5cdd1959605a1b6044820152606401610a87565b600087815260086020526040902080548290811061264357634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160301b90046001600160a01b031694506108ee9350505050565b6105308133612e33565b6126a1604080516080810190915280600081526020016000815260006020820181905260409091015290565b6000600a83815481106126c457634e487b7160e01b600052603260045260246000fd5b6000918252602080832086845260079091526040909220910191506001825460ff16600681111561270557634e487b7160e01b600052602160045260246000fd5b1461274b5760405162461bcd60e51b8152602060048201526016602482015275526166666c6520696e2077726f6e672073746174757360501b6044820152606401610a87565b805482546001600160801b03918216600160401b90910490911610156127b35760405162461bcd60e51b815260206004820152601760248201527f4e6f7420656e6f7567682066756e6473207261697365640000000000000000006044820152606401610a87565b81548154600160401b9091046001600160801b03908116600160801b9092041611156128215760405162461bcd60e51b815260206004820152601860248201527f446573697265642066756e6473206e6f742072616973656400000000000000006044820152606401610a87565b815460ff19166004178083556040516001600160801b03600160401b90920491909116815284907ff2be214756d2fbc1e781d10809ddef33000009d805be55356bb348134ce21c689060200160405180910390a2604080516080810190915282548390829060ff1660068111156128a857634e487b7160e01b600052602160045260246000fd5b60068111156128c757634e487b7160e01b600052602160045260246000fd5b81528154602090910190610100900460ff1660028111156128f857634e487b7160e01b600052602160045260246000fd5b600281111561291757634e487b7160e01b600052602160045260246000fd5b8152905462010000810465ffffffffffff166020830152600160401b90046001600160801b0316604090910152949350505050565b6003546040516370a0823160e01b8152306004820152600091906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a082319060240160206040518083038186803b1580156129b257600080fd5b505afa1580156129c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ea9190613865565b1015612a4c5760405162461bcd60e51b815260206004820152602b60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e74726163742060448201526a1dda5d1a0819985d58d95d60aa1b6064820152608401610a87565b60006108ee600254600354612e97565b612a6682826120a7565b611444576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055612a9c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612aea82826120a7565b15611444576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b604080516080810190915260009080828152602001836002811115612b7a57634e487b7160e01b600052602160045260246000fd5b81526000602082018190526040909101819052600a8054600181810183559190925282517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a890920180549394508493909291839160ff191690836006811115612bf357634e487b7160e01b600052602160045260246000fd5b021790555060208201518154829061ff001916610100836002811115612c2957634e487b7160e01b600052602160045260246000fd5b0217905550604082015181546060909301516001600160801b0316600160401b02600160401b600160c01b031965ffffffffffff90921662010000029190911662010000600160c01b0319909316929092179190911790555050565b6000828152600560209081526040808320815180830190925280548252600101549181018290529190612cb89084613ea6565b612cc3906001613d4a565b60408051808201825285815260208082018481528651600090815260048352849020835181559051600190910155855183518881529182018590529394509092917f7c40e661b8212d0c4f60ac6e6ebed99c28680c7b3ede5b82f3b0254543f62fca910160405180910390a28251612d3b9083613029565b5050505050565b8154600090612d53575060006108ee565b82546000905b80821015612dc6576000612d6d83836133e6565b905084868281548110612d9057634e487b7160e01b600052603260045260246000fd5b60009182526020909120015465ffffffffffff161115612db257809150612dc0565b612dbd816001613d4a565b92505b50612d59565b600082118015612e1257508385612dde600185613e0b565b81548110612dfc57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015465ffffffffffff16145b15612e2b57612e22600183613e0b565b925050506108ee565b5090506108ee565b612e3d82826120a7565b61144457612e55816001600160a01b03166014613408565b612e60836020613408565b604051602001612e71929190613ac9565b60408051601f198184030181529082905262461bcd60e51b8252610a8791600401613c8d565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000084866000604051602001612f07929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612f3493929190613b3e565b602060405180830381600087803b158015612f4e57600080fd5b505af1158015612f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8691906136f8565b50600083815260016020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a09091019092528151918301919091209387905290829052612fe191613d4a565b6000858152600160205260409020556130218482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b949350505050565b60006009838154811061304c57634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020190506000600a848154811061307f57634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506002815460ff1660068111156130b257634e487b7160e01b600052602160045260246000fd5b14806130e157506004815460ff1660068111156130df57634e487b7160e01b600052602160045260246000fd5b145b6131265760405162461bcd60e51b8152602060048201526016602482015275526166666c6520696e2077726f6e672073746174757360501b6044820152606401610a87565b6004820183905561313784846124c5565b6002830180546001600160a01b039283166001600160a01b0319909116178155825460ff1916600517835554600184015460405160009392909216918381818185875af1925050503d80600081146131ab576040519150601f19603f3d011682016040523d82523d6000602084013e6131b0565b606091505b50509050806131d15760405162461bcd60e51b8152600401610a8790613ca0565b82548254600091612710916131fe9165ffffffffffff1690600160401b90046001600160801b0316613dbd565b6132089190613d83565b83546001600160801b03918216925060009161322e918491600160401b90910416613e0b565b60038601546040519192506000916001600160a01b039091169083908381818185875af1925050503d8060008114613282576040519150601f19603f3d011682016040523d82523d6000602084013e613287565b606091505b50509050806132a85760405162461bcd60e51b8152600401610a8790613ca0565b600b546040516000916001600160a01b03169085908381818185875af1925050503d80600081146132f5576040519150601f19603f3d011682016040523d82523d6000602084013e6132fa565b606091505b50509050806133435760405162461bcd60e51b81526020600482015260156024820152744661696c65642073656e642045746820746f204d5760581b6044820152606401610a87565b887f7378e11c2b0ec7514bbf7ba369980eedcba0bca03e116dc9e7138f7748e211d68560405161337591815260200190565b60405180910390a26002870154865460408051600160401b9092046001600160801b03168252602082018b90526001600160a01b03909216918b917fe0b2a72a0644b093aac275024c05c7c28851a0b572557a32241d13634a0f3e08910160405180910390a3505050505050505050565b60006133f56002848418613da9565b61340190848416613d4a565b9392505050565b60606000613417836002613dec565b613422906002613d4a565b67ffffffffffffffff81111561344857634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613472576020820181803683370190505b509050600360fc1b8160008151811061349b57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106134d857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006134fc846002613dec565b613507906001613d4a565b90505b600181111561359b576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061354957634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061356d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361359481613e4e565b905061350a565b5083156134015760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a87565b80356135f581613f12565b919050565b8035600381106135f557600080fd5b80356001600160801b03811681146135f557600080fd5b803565ffffffffffff811681146135f557600080fd5b600060208284031215613647578081fd5b813561340181613f12565b60008060408385031215613664578081fd5b823561366f81613f12565b946020939093013593505050565b60008060008060808587031215613692578182fd5b843561369d81613f12565b93506020850135925060408501356136b481613f12565b9396929550929360600135925050565b6000806000606084860312156136d8578283fd5b83356136e381613f12565b95602085013595506040909401359392505050565b600060208284031215613709578081fd5b81518015158114613401578182fd5b600060208284031215613729578081fd5b5035919050565b60008060408385031215613742578182fd5b82359150602083013561375481613f12565b809150509250929050565b60008060408385031215613771578182fd5b50508035926020909101359150565b600060208284031215613791578081fd5b81356001600160e01b031981168114613401578182fd5b600080600080600080600060c0888a0312156137c2578283fd5b6137cb88613609565b9650602088013595506137e060408901613609565b9450606088013567ffffffffffffffff808211156137fc578485fd5b818a0191508a601f83011261380f578485fd5b81358181111561381d578586fd5b8b6020606083028501011115613831578586fd5b60208301965080955050505061384960808901613620565b915061385760a089016135fa565b905092959891949750929550565b600060208284031215613876578081fd5b5051919050565b6000806040838503121561388f578182fd5b8235915060208084013567ffffffffffffffff808211156138ae578384fd5b818601915086601f8301126138c1578384fd5b8135818111156138d3576138d3613efc565b8060051b604051601f19603f830116810181811085821117156138f8576138f8613efc565b604052828152858101935084860182860187018b1015613916578788fd5b8795505b8386101561393f5761392b816135ea565b85526001959095019493860193860161391a565b508096505050505050509250929050565b60008060008060608587031215613965578182fd5b84359350602085013567ffffffffffffffff80821115613983578384fd5b818701915087601f830112613996578384fd5b8135818111156139a4578485fd5b8860208260051b85010111156139b8578485fd5b60208301955080945050505060408501356139d281613f12565b939692955090935050565b6000806000606084860312156139f1578081fd5b83359250613a0160208501613620565b91506040840135613a1181613f12565b809150509250925092565b600060208284031215613a2d578081fd5b61340182613620565b6000815180845260208085019450808401835b83811015613a6e5781516001600160a01b031687529582019590820190600101613a49565b509495945050505050565b60008151808452613a91816020860160208601613e22565b601f01601f19169290920160200192915050565b60038110613ab557613ab5613ee6565b9052565b60078110613ab557613ab5613ee6565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b01816017850160208801613e22565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613b32816028840160208801613e22565b01602801949350505050565b60018060a01b0384168152826020820152606060408201526000613b656060830184613a79565b95945050505050565b606081526000613b816060830186613a36565b905083602083015265ffffffffffff83166040830152949350505050565b606081526000613bb26060830186613a36565b65ffffffffffff94851660208401529290931660409091015292915050565b602080825282518282018190526000919060409081850190868401855b82811015613c24578151805165ffffffffffff1685528601516001600160a01b0316868501529284019290850190600101613bee565b5091979650505050505050565b82151581526040602082015260006130216040830184613a79565b60808101613c5a8287613ab9565b613c676020830186613aa5565b65ffffffffffff841660408301526001600160801b038316606083015295945050505050565b6020815260006134016020830184613a79565b6020808252601490820152732330b4b632b2103a379039b2b7321022ba3432b960611b604082015260600190565b6000608082019050613ce1828451613ab9565b6020830151613cf36020840182613aa5565b5065ffffffffffff60408401511660408301526001600160801b03606084015116606083015292915050565b60006001600160801b03808316818516808303821115613d4157613d41613eba565b01949350505050565b60008219821115613d5d57613d5d613eba565b500190565b600065ffffffffffff808316818516808303821115613d4157613d41613eba565b60006001600160801b0380841680613d9d57613d9d613ed0565b92169190910492915050565b600082613db857613db8613ed0565b500490565b60006001600160801b0380831681851681830481118215151615613de357613de3613eba565b02949350505050565b6000816000190483118215151615613e0657613e06613eba565b500290565b600082821015613e1d57613e1d613eba565b500390565b60005b83811015613e3d578181015183820152602001613e25565b83811115610cb85750506000910152565b600081613e5d57613e5d613eba565b506000190190565b6000600019821415613e7957613e79613eba565b5060010190565b600065ffffffffffff80831681811415613e9c57613e9c613eba565b6001019392505050565b600082613eb557613eb5613ed0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461053057600080fdfe523a704056dcd17bcf83bed8b68c59416dac1119be77755efe3bde0a64e46e0ca264697066735822122036787320047eb33c762fc0bbdd5c7c3e7e9a3580100ff91636a7fff972c0077a64736f6c63430008040033000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986caaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af4450000000000000000000000000000000000000000000000000000000000000001
Deployed Bytecode
0x60806040526004361061021a5760003560e01c806353b7a59b1161012357806393a75d02116100ab578063d649214c1161006f578063d649214c14610789578063ddba6e6b146107a9578063eb99038c1461080f578063f369145514610833578063f5b541a61461085357600080fd5b806393a75d02146106c357806394985ddd146106f0578063a217fddf14610710578063babdf60b14610725578063d547741f1461076957600080fd5b80636ecc20da116100f25780636ecc20da146106085780637c903fc01461061b5780637fa4cacb1461064f57806381d12c581461066f57806391d14854146106a357600080fd5b806353b7a59b146105335780635d4bc0ce1461056b5780635fba3171146105c85780636371ba0d146105e857600080fd5b8063248a9ca3116101a657806336568abe1161017557806336568abe14610478578063365e36581461049857806336734e34146104c55780633a3956c2146104e55780634239a50c1461051557600080fd5b8063248a9ca3146103b15780632a596800146103ef5780632f2ff15d14610438578063317f30591461045857600080fd5b80630b148ff0116101ed5780630b148ff01461031b5780630df716021461033d5780631e6cd3951461035d5780631fe968571461037d578063236854961461039e57600080fd5b8063013805c51461021f57806301ffc9a71461026a578063039be5581461029a578063043a1c9a146102fb575b600080fd5b34801561022b57600080fd5b5061023f61023a36600461375f565b610875565b6040805165ffffffffffff90931683526001600160a01b039091166020830152015b60405180910390f35b34801561027657600080fd5b5061028a610285366004613780565b6108bd565b6040519015158152602001610261565b3480156102a657600080fd5b506102db6102b5366004613718565b6007602052600090815260409020546001600160801b0380821691600160801b90041682565b604080516001600160801b03938416815292909116602083015201610261565b34801561030757600080fd5b5061028a610316366004613652565b6108f4565b34801561032757600080fd5b5061033b6103363660046139dd565b61098d565b005b34801561034957600080fd5b5061033b610358366004613718565b610c49565b34801561036957600080fd5b5061028a610378366004613718565b610cbe565b34801561038957600080fd5b5061028a610398366004613636565b50600090565b61033b6103ac36600461375f565b610de9565b3480156103bd57600080fd5b506103e16103cc366004613718565b60009081526020819052604090206001015490565b604051908152602001610261565b3480156103fb57600080fd5b5061042361040a366004613718565b6005602052600090815260409020805460019091015482565b60408051928352602083019190915201610261565b34801561044457600080fd5b5061033b610453366004613730565b6111b4565b34801561046457600080fd5b5061033b610473366004613718565b6111de565b34801561048457600080fd5b5061033b610493366004613730565b6113ca565b3480156104a457600080fd5b506104b86104b3366004613718565b611448565b6040516102619190613bd1565b3480156104d157600080fd5b5061033b6104e036600461387d565b6114d6565b3480156104f157600080fd5b50610505610500366004613718565b61171f565b6040516102619493929190613c4c565b34801561052157600080fd5b5061033b610530366004613718565b50565b34801561053f57600080fd5b50600b54610553906001600160a01b031681565b6040516001600160a01b039091168152602001610261565b34801561057757600080fd5b5061058b610586366004613718565b61176b565b6040805165ffffffffffff909616865260208601949094526001600160a01b0392831693850193909352166060830152608082015260a001610261565b3480156105d457600080fd5b5061033b6105e3366004613718565b6117c2565b3480156105f457600080fd5b506103e16106033660046137a8565b611a61565b61033b610616366004613718565b611f17565b34801561062757600080fd5b506103e17fde5ee446972f4e39ab62c03aa34b2096680a875c3fdb3eb2f947cbb93341c05881565b34801561065b57600080fd5b5061033b61066a366004613636565b612079565b34801561067b57600080fd5b5061042361068a366004613718565b6004602052600090815260409020805460019091015482565b3480156106af57600080fd5b5061028a6106be366004613730565b6120a7565b3480156106cf57600080fd5b506106e36106de366004613718565b6120d0565b6040516102619190613cce565b3480156106fc57600080fd5b5061033b61070b36600461375f565b6121fc565b34801561071c57600080fd5b506103e1600081565b34801561073157600080fd5b5061075b61074036600461367d565b60408051602081019091526000815260019094509492505050565b604051610261929190613c31565b34801561077557600080fd5b5061033b610784366004613730565b61227e565b34801561079557600080fd5b5061033b6107a4366004613950565b6122a3565b3480156107b557600080fd5b506107ed6107c4366004613718565b600660205260009081526040902080546001820154600290920154909165ffffffffffff169083565b6040805193845265ffffffffffff909216602084015290820152606001610261565b34801561081b57600080fd5b5061028a61082a3660046136c4565b60009392505050565b34801561083f57600080fd5b5061055361084e36600461375f565b6124c5565b34801561085f57600080fd5b506103e1600080516020613f2883398151915281565b6008602052816000526040600020818154811061089157600080fd5b60009182526020909120015465ffffffffffff81169250600160301b90046001600160a01b0316905082565b60006001600160e01b03198216637965db0b60e01b14806108ee57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6000806009838154811061091857634e487b7160e01b600052603260045260246000fd5b60009182526020918290206040805160a0810182526005909302909101805465ffffffffffff16835260018101549383019390935260028301546001600160a01b0390811691830191909152600383015481166060830181905260049093015460809092019190915285161491505092915050565b7fde5ee446972f4e39ab62c03aa34b2096680a875c3fdb3eb2f947cbb93341c0586109b78161266b565b6000600a85815481106109da57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001905060018154610100900460ff166002811115610a1257634e487b7160e01b600052602160045260246000fd5b1480610a46575060028154610100900460ff166002811115610a4457634e487b7160e01b600052602160045260246000fd5b145b610a905760405162461bcd60e51b8152602060048201526016602482015275115b9d1c9e481d1e5c19481b9bdd08185b1b1bddd95960521b60448201526064015b60405180910390fd5b60006040518060400160405280868460000160029054906101000a900465ffffffffffff16610abf9190613d62565b65ffffffffffff90811682526001600160a01b0380881660209384015260008a8152600884526040812080546001810182559082529084902085519101805494860151909216600160301b026001600160d01b03199094169083161792909217909155835491925086918491600291610b4091859162010000900416613d62565b92506101000a81548165ffffffffffff021916908365ffffffffffff1602179055506000600167ffffffffffffffff811115610b8c57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610bb5578160200160208202803683370190505b5090508481600081518110610bda57634e487b7160e01b600052603260045260246000fd5b6001600160a01b0390921660209283029190910190910152825460405188917f4da4f5fab0816c65315b6f5d15f879f96b98661133d7b3787788f291367604fb91610c389185918b9165ffffffffffff620100009091041690613b9f565b60405180910390a250505050505050565b600080516020613f28833981519152610c618161266b565b6000610c6c83612675565b90506000610c7861294c565b9050610cb884836040015165ffffffffffff1683604080518082018252938452602080850193845260009283526005905290209151825551600190910155565b50505050565b600080600a8381548110610ce257634e487b7160e01b600052603260045260246000fd5b60009182526020909120604080516080810190915291018054829060ff166006811115610d1f57634e487b7160e01b600052602160045260246000fd5b6006811115610d3e57634e487b7160e01b600052602160045260246000fd5b81528154602090910190610100900460ff166002811115610d6f57634e487b7160e01b600052602160045260246000fd5b6002811115610d8e57634e487b7160e01b600052602160045260246000fd5b8152905462010000810465ffffffffffff166020830152600160401b90046001600160801b03166040909101529050600181516006811115610de057634e487b7160e01b600052602160045260246000fd5b14159392505050565b6000600a8381548110610e0c57634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506001815460ff166006811115610e3f57634e487b7160e01b600052602160045260246000fd5b14610e7f5760405163efeb42cf60e01b815260206004820152600f60248201526e139bdd081a5b881050d0d154151151608a1b6044820152606401610a87565b60018154610100900460ff166002811115610eaa57634e487b7160e01b600052602160045260246000fd5b1415610ef25760405163efeb42cf60e01b8152602060048201526016602482015275115b9d1c9e481d1e5c19481b9bdd08185b1b1bddd95960521b6044820152606401610a87565b81610f2f5760405163efeb42cf60e01b815260206004820152600c60248201526b0686f774d616e7920697320360a41b6044820152606401610a87565b60008281526006602090815260409182902082516060810184528154808252600183015465ffffffffffff1693820193909352600290910154928101929092528414610fb35760405163efeb42cf60e01b81526020600482015260126024820152711259081b9bdd081a5b881c9859999b19525960721b6044820152606401610a87565b602081015165ffffffffffff81166110015760405163efeb42cf60e01b815260206004820152601060248201526f1259081b9bdd081cdd5c1c1bdc9d195960821b6044820152606401610a87565b816040015134146110615760405163efeb42cf60e01b8152602060048201526024808201527f6d73672e76616c7565206d75737420626520657175616c20746f2074686520706044820152637269636560e01b6064820152608401610a87565b8254604080518082019091526201000090910465ffffffffffff16906000908061108b8585613d62565b65ffffffffffff90811682523360209283015260008a8152600880845260408220805460018101825590835291849020855192018054948601516001600160a01b0316600160301b026001600160d01b03199095169290931691909117929092179055865491925034918791906111149084906001600160801b03600160401b90910416613d1f565b92506101000a8154816001600160801b0302191690836001600160801b0316021790555082826111449190613d62565b855467ffffffffffff000019166201000065ffffffffffff9283168102919091178088556040805192909104909216815260208101889052339189917fd746af8dc82f9bed98cea0fe0264eb1c3d2e5f7bcc77fc5efb429c79df407887910160405180910390a350505050505050565b6000828152602081905260409020600101546111cf8161266b565b6111d98383612a5c565b505050565b600080516020613f288339815191526111f68161266b565b6000600a838154811061121957634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506006815460ff16600681111561124c57634e487b7160e01b600052602160045260246000fd5b148061127b57506003815460ff16600681111561127957634e487b7160e01b600052602160045260246000fd5b145b6112b65760405162461bcd60e51b815260206004820152600c60248201526b57726f6e672073746174757360a01b6044820152606401610a87565b805460ff1916600317808255600b546040516000926001600160a01b03909216916001600160801b03600160401b90910416908381818185875af1925050503d8060008114611321576040519150601f19603f3d011682016040523d82523d6000602084013e611326565b606091505b505090508061136d5760405162461bcd60e51b81526020600482015260136024820152724661696c2073656e642045746820746f204d5760681b6044820152606401610a87565b8154604051600160401b9091046001600160801b0316815284907fcdef6558dae40f2699846eedf449462daab85b1224ad7f077569ba91aaa949259060200160405180910390a2508054600160401b600160c01b03191690555050565b6001600160a01b038116331461143a5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610a87565b6114448282612ae0565b5050565b606060086000838152602001908152602001600020805480602002602001604051908101604052809291908181526020016000905b828210156114cb576000848152602090819020604080518082019091529084015465ffffffffffff81168252600160301b90046001600160a01b03168183015282526001909201910161147d565b505050509050919050565b600080516020613f288339815191526114ee8161266b565b6000600a848154811061151157634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506001815460ff16600681111561154457634e487b7160e01b600052602160045260246000fd5b146115915760405162461bcd60e51b815260206004820152601960248201527f526166666c65206973206e6f7420696e206163636570746564000000000000006044820152606401610a87565b82516000805b828110156116935760008682815181106115c157634e487b7160e01b600052603260045260246000fd5b6020026020010151905060006040518060400160405280848860000160029054906101000a900465ffffffffffff1665ffffffffffff166116029190613d4a565b61160d906001613d4a565b65ffffffffffff90811682526001600160a01b0380861660209384015260008d8152600884526040812080546001810182559082529084902085519101805494860151909216600160301b026001600160d01b0319909416921691909117919091179055905061167c84613e80565b93505050808061168b90613e65565b915050611597565b5082546116af90829062010000900465ffffffffffff16613d62565b835467ffffffffffff000019166201000065ffffffffffff92831681029190911780865560405189937f4da4f5fab0816c65315b6f5d15f879f96b98661133d7b3787788f291367604fb9361170f938b9389939290910490911690613b6e565b60405180910390a2505050505050565b600a818154811061172f57600080fd5b60009182526020909120015460ff80821692506101008204169062010000810465ffffffffffff1690600160401b90046001600160801b031684565b6009818154811061177b57600080fd5b60009182526020909120600590910201805460018201546002830154600384015460049094015465ffffffffffff909316945090926001600160a01b039182169291169085565b600080516020613f288339815191526117da8161266b565b6000600983815481106117fd57634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020190506000600a848154811061183057634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506005815460ff16600681111561186357634e487b7160e01b600052602160045260246000fd5b1415801561189557506003815460ff16600681111561189257634e487b7160e01b600052602160045260246000fd5b14155b80156118c557506002815460ff1660068111156118c257634e487b7160e01b600052602160045260246000fd5b14155b80156118f557506004815460ff1660068111156118f257634e487b7160e01b600052602160045260246000fd5b14155b801561192557506006815460ff16600681111561192257634e487b7160e01b600052602160045260246000fd5b14155b6119605760405162461bcd60e51b815260206004820152600c60248201526b57726f6e672073746174757360a01b6044820152606401610a87565b6001815460ff16600681111561198657634e487b7160e01b600052602160045260246000fd5b1415611a0757600382015460018301546040516000926001600160a01b031691908381818185875af1925050503d80600081146119df576040519150601f19603f3d011682016040523d82523d6000602084013e6119e4565b606091505b5050905080611a055760405162461bcd60e51b8152600401610a8790613ca0565b505b805460ff19166006178082556040516001600160801b03600160401b90920491909116815284907fd512a34b0f0618078770fcd85d974df1ab46a7882e8b3d45aa91764f4961aed29060200160405180910390a250505050565b6000600080516020613f28833981519152611a7b8161266b565b6113888465ffffffffffff161115611acb5760405162461bcd60e51b81526020600482015260136024820152720c6dedadad2e6e6d2dedc40e8dede40d0d2ced606b1b6044820152606401610a87565b6040805160a08101825265ffffffffffff8681168252602082018b81526000938301848152606084018581526080850186815260098054600181018255975285517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7af6005909802978801805465ffffffffffff1916919096161790945591517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b0860155517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b1850180546001600160a01b03199081166001600160a01b039384161790915591517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b2860180549093169116179055517f6e1540171b6c0c960b71a7020d9f60077f6af931a8bbf590da0223dacf75c7b390920191909155611c1084612b45565b600954600090611c2290600190613e0b565b905086611c5d5760405162461bcd60e51b81526020600482015260096024820152684e6f2070726963657360b81b6044820152606401610a87565b60005b87811015611df6576000898983818110611c8a57634e487b7160e01b600052603260045260246000fd5b9050606002016020016020810190611ca29190613a1c565b65ffffffffffff1611611ce95760405162461bcd60e51b815260206004820152600f60248201526e06e756d456e7472696573206973203608c1b6044820152606401610a87565b600060405180606001604052808481526020018b8b85818110611d1c57634e487b7160e01b600052603260045260246000fd5b9050606002016020016020810190611d349190613a1c565b65ffffffffffff1681526020018b8b85818110611d6157634e487b7160e01b600052603260045260246000fd5b90506060020160400135815250905080600660008c8c86818110611d9557634e487b7160e01b600052603260045260246000fd5b60600291909101358252506020808201929092526040908101600020835181559183015160018301805465ffffffffffff191665ffffffffffff90921691909117905591909101516002909101555080611dee81613e65565b915050611c60565b506040805180820182526001600160801b03808c1682528d8116602080840191825260008681526007909152848120935191518316600160801b02919092161790915590518b9183917ff6f5afeb49bc62176d1efaa06a1753999cc29bf378f1004ea916f37f41d7638a9190a360408051808201825260018082523360208084019182526000868152600882529485208054938401815580865290852084519301805492516001600160a01b0316600160301b026001600160d01b031990931665ffffffffffff949094169390931791909117909155838352805491929091611eef57634e487b7160e01b600052603260045260246000fd5b600091825260209091200180546001600160d01b0319169055509a9950505050505050505050565b6000600a8281548110611f3a57634e487b7160e01b600052603260045260246000fd5b906000526020600020019050600060098381548110611f6957634e487b7160e01b600052603260045260246000fd5b6000918252602082206005909102019150825460ff166006811115611f9e57634e487b7160e01b600052602160045260246000fd5b14611fe05760405162461bcd60e51b8152602060048201526012602482015271149859999b19481b9bdd0810d4915055115160721b6044820152606401610a87565b348160010154146120265760405162461bcd60e51b815260206004820152601060248201526f141c9a5e99481b9bdd081cdd185ad95960821b6044820152606401610a87565b815460ff19166001178255600381018054336001600160a01b0319909116811790915560405184907f8bb509eedfd1c4847b0a8a2b4493cf2ebb9970dc367e477cd2a8523e212dc1db90600090a3505050565b60006120848161266b565b50600b80546001600160a01b0319166001600160a01b0392909216919091179055565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b6120fc604080516080810190915280600081526020016000815260006020820181905260409091015290565b600a828154811061211d57634e487b7160e01b600052603260045260246000fd5b60009182526020909120604080516080810190915291018054829060ff16600681111561215a57634e487b7160e01b600052602160045260246000fd5b600681111561217957634e487b7160e01b600052602160045260246000fd5b81528154602090910190610100900460ff1660028111156121aa57634e487b7160e01b600052602160045260246000fd5b60028111156121c957634e487b7160e01b600052602160045260246000fd5b8152905462010000810465ffffffffffff166020830152600160401b90046001600160801b031660409091015292915050565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795216146122745760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610a87565b6114448282612c85565b6000828152602081905260409020600101546122998161266b565b6111d98383612ae0565b600080516020613f288339815191526122bb8161266b565b6000805b848110156124845760008781526008602052604081208787848181106122f557634e487b7160e01b600052603260045260246000fd5b9050602002013560016123089190613d4a565b8154811061232657634e487b7160e01b600052603260045260246000fd5b600091825260209091200180549091506001600160a01b03868116600160301b90920416146123975760405162461bcd60e51b815260206004820152601e60248201527f456e74727920646964206e6f742062656c6f6e6720746f20706c6179657200006044820152606401610a87565b80546601000000000000600160d01b031916815560008787848181106123cd57634e487b7160e01b600052603260045260246000fd5b90506020020135600014156123e45750600061244e565b600089815260086020526040902088888581811061241257634e487b7160e01b600052603260045260246000fd5b905060200201358154811061243757634e487b7160e01b600052603260045260246000fd5b60009182526020909120015465ffffffffffff1690505b815461246390829065ffffffffffff16613e0b565b61246d9085613d4a565b93505050808061247c90613e65565b9150506122bf565b50604080518281526001600160a01b038516602082015287917f2cca80c1af5abb202a642a502875436822768d733462843a7c3a902b0fad99d0910161170f565b600082815260086020526040812081906124df9084612d42565b6000858152600860205260408120805492935090918390811061251257634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160301b90046001600160a01b03169050801561253f5791506108ee9050565b6000825b811580156125985750600087815260086020526040812080548390811061257a57634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160301b90046001600160a01b0316145b156125cf57806125c4576000878152600860205260409020546125bd90600190613e0b565b9050612543565b6125bd600182613e0b565b81156126155760405162461bcd60e51b8152602060048201526015602482015274105b1b081d5cd95c9cc8189b1858dadb1a5cdd1959605a1b6044820152606401610a87565b600087815260086020526040902080548290811061264357634e487b7160e01b600052603260045260246000fd5b600091825260209091200154600160301b90046001600160a01b031694506108ee9350505050565b6105308133612e33565b6126a1604080516080810190915280600081526020016000815260006020820181905260409091015290565b6000600a83815481106126c457634e487b7160e01b600052603260045260246000fd5b6000918252602080832086845260079091526040909220910191506001825460ff16600681111561270557634e487b7160e01b600052602160045260246000fd5b1461274b5760405162461bcd60e51b8152602060048201526016602482015275526166666c6520696e2077726f6e672073746174757360501b6044820152606401610a87565b805482546001600160801b03918216600160401b90910490911610156127b35760405162461bcd60e51b815260206004820152601760248201527f4e6f7420656e6f7567682066756e6473207261697365640000000000000000006044820152606401610a87565b81548154600160401b9091046001600160801b03908116600160801b9092041611156128215760405162461bcd60e51b815260206004820152601860248201527f446573697265642066756e6473206e6f742072616973656400000000000000006044820152606401610a87565b815460ff19166004178083556040516001600160801b03600160401b90920491909116815284907ff2be214756d2fbc1e781d10809ddef33000009d805be55356bb348134ce21c689060200160405180910390a2604080516080810190915282548390829060ff1660068111156128a857634e487b7160e01b600052602160045260246000fd5b60068111156128c757634e487b7160e01b600052602160045260246000fd5b81528154602090910190610100900460ff1660028111156128f857634e487b7160e01b600052602160045260246000fd5b600281111561291757634e487b7160e01b600052602160045260246000fd5b8152905462010000810465ffffffffffff166020830152600160401b90046001600160801b0316604090910152949350505050565b6003546040516370a0823160e01b8152306004820152600091906001600160a01b037f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca16906370a082319060240160206040518083038186803b1580156129b257600080fd5b505afa1580156129c6573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906129ea9190613865565b1015612a4c5760405162461bcd60e51b815260206004820152602b60248201527f4e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e74726163742060448201526a1dda5d1a0819985d58d95d60aa1b6064820152608401610a87565b60006108ee600254600354612e97565b612a6682826120a7565b611444576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055612a9c3390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612aea82826120a7565b15611444576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b604080516080810190915260009080828152602001836002811115612b7a57634e487b7160e01b600052602160045260246000fd5b81526000602082018190526040909101819052600a8054600181810183559190925282517fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a890920180549394508493909291839160ff191690836006811115612bf357634e487b7160e01b600052602160045260246000fd5b021790555060208201518154829061ff001916610100836002811115612c2957634e487b7160e01b600052602160045260246000fd5b0217905550604082015181546060909301516001600160801b0316600160401b02600160401b600160c01b031965ffffffffffff90921662010000029190911662010000600160c01b0319909316929092179190911790555050565b6000828152600560209081526040808320815180830190925280548252600101549181018290529190612cb89084613ea6565b612cc3906001613d4a565b60408051808201825285815260208082018481528651600090815260048352849020835181559051600190910155855183518881529182018590529394509092917f7c40e661b8212d0c4f60ac6e6ebed99c28680c7b3ede5b82f3b0254543f62fca910160405180910390a28251612d3b9083613029565b5050505050565b8154600090612d53575060006108ee565b82546000905b80821015612dc6576000612d6d83836133e6565b905084868281548110612d9057634e487b7160e01b600052603260045260246000fd5b60009182526020909120015465ffffffffffff161115612db257809150612dc0565b612dbd816001613d4a565b92505b50612d59565b600082118015612e1257508385612dde600185613e0b565b81548110612dfc57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015465ffffffffffff16145b15612e2b57612e22600183613e0b565b925050506108ee565b5090506108ee565b612e3d82826120a7565b61144457612e55816001600160a01b03166014613408565b612e60836020613408565b604051602001612e71929190613ac9565b60408051601f198184030181529082905262461bcd60e51b8252610a8791600401613c8d565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795284866000604051602001612f07929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401612f3493929190613b3e565b602060405180830381600087803b158015612f4e57600080fd5b505af1158015612f62573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612f8691906136f8565b50600083815260016020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a09091019092528151918301919091209387905290829052612fe191613d4a565b6000858152600160205260409020556130218482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b949350505050565b60006009838154811061304c57634e487b7160e01b600052603260045260246000fd5b906000526020600020906005020190506000600a848154811061307f57634e487b7160e01b600052603260045260246000fd5b600091825260209091200190506002815460ff1660068111156130b257634e487b7160e01b600052602160045260246000fd5b14806130e157506004815460ff1660068111156130df57634e487b7160e01b600052602160045260246000fd5b145b6131265760405162461bcd60e51b8152602060048201526016602482015275526166666c6520696e2077726f6e672073746174757360501b6044820152606401610a87565b6004820183905561313784846124c5565b6002830180546001600160a01b039283166001600160a01b0319909116178155825460ff1916600517835554600184015460405160009392909216918381818185875af1925050503d80600081146131ab576040519150601f19603f3d011682016040523d82523d6000602084013e6131b0565b606091505b50509050806131d15760405162461bcd60e51b8152600401610a8790613ca0565b82548254600091612710916131fe9165ffffffffffff1690600160401b90046001600160801b0316613dbd565b6132089190613d83565b83546001600160801b03918216925060009161322e918491600160401b90910416613e0b565b60038601546040519192506000916001600160a01b039091169083908381818185875af1925050503d8060008114613282576040519150601f19603f3d011682016040523d82523d6000602084013e613287565b606091505b50509050806132a85760405162461bcd60e51b8152600401610a8790613ca0565b600b546040516000916001600160a01b03169085908381818185875af1925050503d80600081146132f5576040519150601f19603f3d011682016040523d82523d6000602084013e6132fa565b606091505b50509050806133435760405162461bcd60e51b81526020600482015260156024820152744661696c65642073656e642045746820746f204d5760581b6044820152606401610a87565b887f7378e11c2b0ec7514bbf7ba369980eedcba0bca03e116dc9e7138f7748e211d68560405161337591815260200190565b60405180910390a26002870154865460408051600160401b9092046001600160801b03168252602082018b90526001600160a01b03909216918b917fe0b2a72a0644b093aac275024c05c7c28851a0b572557a32241d13634a0f3e08910160405180910390a3505050505050505050565b60006133f56002848418613da9565b61340190848416613d4a565b9392505050565b60606000613417836002613dec565b613422906002613d4a565b67ffffffffffffffff81111561344857634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015613472576020820181803683370190505b509050600360fc1b8160008151811061349b57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106134d857634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060006134fc846002613dec565b613507906001613d4a565b90505b600181111561359b576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061354957634e487b7160e01b600052603260045260246000fd5b1a60f81b82828151811061356d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535060049490941c9361359481613e4e565b905061350a565b5083156134015760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610a87565b80356135f581613f12565b919050565b8035600381106135f557600080fd5b80356001600160801b03811681146135f557600080fd5b803565ffffffffffff811681146135f557600080fd5b600060208284031215613647578081fd5b813561340181613f12565b60008060408385031215613664578081fd5b823561366f81613f12565b946020939093013593505050565b60008060008060808587031215613692578182fd5b843561369d81613f12565b93506020850135925060408501356136b481613f12565b9396929550929360600135925050565b6000806000606084860312156136d8578283fd5b83356136e381613f12565b95602085013595506040909401359392505050565b600060208284031215613709578081fd5b81518015158114613401578182fd5b600060208284031215613729578081fd5b5035919050565b60008060408385031215613742578182fd5b82359150602083013561375481613f12565b809150509250929050565b60008060408385031215613771578182fd5b50508035926020909101359150565b600060208284031215613791578081fd5b81356001600160e01b031981168114613401578182fd5b600080600080600080600060c0888a0312156137c2578283fd5b6137cb88613609565b9650602088013595506137e060408901613609565b9450606088013567ffffffffffffffff808211156137fc578485fd5b818a0191508a601f83011261380f578485fd5b81358181111561381d578586fd5b8b6020606083028501011115613831578586fd5b60208301965080955050505061384960808901613620565b915061385760a089016135fa565b905092959891949750929550565b600060208284031215613876578081fd5b5051919050565b6000806040838503121561388f578182fd5b8235915060208084013567ffffffffffffffff808211156138ae578384fd5b818601915086601f8301126138c1578384fd5b8135818111156138d3576138d3613efc565b8060051b604051601f19603f830116810181811085821117156138f8576138f8613efc565b604052828152858101935084860182860187018b1015613916578788fd5b8795505b8386101561393f5761392b816135ea565b85526001959095019493860193860161391a565b508096505050505050509250929050565b60008060008060608587031215613965578182fd5b84359350602085013567ffffffffffffffff80821115613983578384fd5b818701915087601f830112613996578384fd5b8135818111156139a4578485fd5b8860208260051b85010111156139b8578485fd5b60208301955080945050505060408501356139d281613f12565b939692955090935050565b6000806000606084860312156139f1578081fd5b83359250613a0160208501613620565b91506040840135613a1181613f12565b809150509250925092565b600060208284031215613a2d578081fd5b61340182613620565b6000815180845260208085019450808401835b83811015613a6e5781516001600160a01b031687529582019590820190600101613a49565b509495945050505050565b60008151808452613a91816020860160208601613e22565b601f01601f19169290920160200192915050565b60038110613ab557613ab5613ee6565b9052565b60078110613ab557613ab5613ee6565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351613b01816017850160208801613e22565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351613b32816028840160208801613e22565b01602801949350505050565b60018060a01b0384168152826020820152606060408201526000613b656060830184613a79565b95945050505050565b606081526000613b816060830186613a36565b905083602083015265ffffffffffff83166040830152949350505050565b606081526000613bb26060830186613a36565b65ffffffffffff94851660208401529290931660409091015292915050565b602080825282518282018190526000919060409081850190868401855b82811015613c24578151805165ffffffffffff1685528601516001600160a01b0316868501529284019290850190600101613bee565b5091979650505050505050565b82151581526040602082015260006130216040830184613a79565b60808101613c5a8287613ab9565b613c676020830186613aa5565b65ffffffffffff841660408301526001600160801b038316606083015295945050505050565b6020815260006134016020830184613a79565b6020808252601490820152732330b4b632b2103a379039b2b7321022ba3432b960611b604082015260600190565b6000608082019050613ce1828451613ab9565b6020830151613cf36020840182613aa5565b5065ffffffffffff60408401511660408301526001600160801b03606084015116606083015292915050565b60006001600160801b03808316818516808303821115613d4157613d41613eba565b01949350505050565b60008219821115613d5d57613d5d613eba565b500190565b600065ffffffffffff808316818516808303821115613d4157613d41613eba565b60006001600160801b0380841680613d9d57613d9d613ed0565b92169190910492915050565b600082613db857613db8613ed0565b500490565b60006001600160801b0380831681851681830481118215151615613de357613de3613eba565b02949350505050565b6000816000190483118215151615613e0657613e06613eba565b500290565b600082821015613e1d57613e1d613eba565b500390565b60005b83811015613e3d578181015183820152602001613e25565b83811115610cb85750506000910152565b600081613e5d57613e5d613eba565b506000190190565b6000600019821415613e7957613e79613eba565b5060010190565b600065ffffffffffff80831681811415613e9c57613e9c613eba565b6001019392505050565b600082613eb557613eb5613ed0565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052602160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b038116811461053057600080fdfe523a704056dcd17bcf83bed8b68c59416dac1119be77755efe3bde0a64e46e0ca264697066735822122036787320047eb33c762fc0bbdd5c7c3e7e9a3580100ff91636a7fff972c0077a64736f6c63430008040033
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986caaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af4450000000000000000000000000000000000000000000000000000000000000001
-----Decoded View---------------
Arg [0] : _vrfCoordinator (address): 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952
Arg [1] : _linkToken (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [2] : _keyHash (bytes32): 0xaa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445
Arg [3] : _mainetFee (bool): True
-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952
Arg [1] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [2] : aa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000001
Loading...
Loading
Loading...
Loading
Loading...
Loading
[ Download: CSV Export ]
[ Download: CSV Export ]
A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.