Polygon Sponsored slots available. Book your slot here!
Contract Overview
My Name Tag:
Not Available, login to update
[ Download CSV Export ]
Contract Name:
LotteryContract
Compiler Version
v0.6.12+commit.27d51765
Optimization Enabled:
Yes with 200 runs
Other Settings:
default evmVersion
Contract Source Code (Solidity Standard Json-Input format)
pragma solidity ^0.6.0; import "./interfaces/IERC20.sol"; import "./VRFConsumerBase.sol"; import "@openzeppelin/contracts/utils/Address.sol"; // import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/utils/ReentrancyGuard.sol"; contract LotteryContract is VRFConsumerBase, ReentrancyGuard, Ownable { using Address for address; using SafeMath for uint256; struct LotteryConfig { uint256 numOfWinners; uint256 playersLimit; uint256 registrationAmount; uint256 adminFeePercentage; uint256 randomSeed; uint256 startedAt; } address[] public lotteryPlayers; address public feeAddress; enum LotteryStatus { NOTSTARTED, INPROGRESS, CLOSED } mapping(uint256 => address) public winnerAddresses; uint256[] public winnerIndexes; uint256 public totalLotteryPool; uint256 public adminFeesAmount; uint256 public rewardPoolAmount; IERC20 public lotteryToken; IERC20 public buyToken; LotteryStatus public lotteryStatus; LotteryConfig public lotteryConfig; bytes32 internal keyHash; uint256 internal fee; uint256 internal randomResult; bool internal areWinnersGenerated; bool internal isRandomNumberGenerated; bool public pauseLottery; uint256 public loserLotteryAmount; // event MaxParticipationCompleted(address indexed _from); event RandomNumberGenerated(uint256 indexed randomness); event WinnersGenerated(uint256[] winnerIndexes); event LotterySettled( uint256 _rewardPoolAmount, uint256 _players, uint256 _adminFees ); event LotteryPaused(); event LotteryUnPaused(); event EmergencyWithdrawn(); // LotterySettled(rewardPoolAmount, players, adminFeesAmount); event LotteryStarted( uint256 playersLimit, uint256 numOfWinners, uint256 registrationAmount, uint256 startedAt ); event LotteryReset(); /** * @dev Sets the value for adminAddress which establishes the Admin of the contract * Only the adminAddress will be able to set the lottery configuration, * start the lottery and reset the lottery. * * It also sets the required fees, keyHash etc. for the ChainLink Oracle RNG * * Also initializes the LOT ERC20 TOKEN that is minted/burned by the participating lottery players. * * The adminAdress value is immutable along with the initial * configuration of VRF Smart Contract. They can only be set once during * construction. */ constructor( IERC20 _buyToken, IERC20 _lotteryToken, address _feeAddress, address _vrfCoordinator, address _link, bytes32 _keyHash ) public VRFConsumerBase( _vrfCoordinator, // VRF Coordinator _link // LINK Token ) Ownable() { feeAddress = _feeAddress; lotteryStatus = LotteryStatus.NOTSTARTED; totalLotteryPool = 0; keyHash = _keyHash; fee = 0.0001 * 10**18; // 0.0001 LINK areWinnersGenerated = false; isRandomNumberGenerated = false; buyToken = _buyToken; // ERC20 contract lotteryToken = _lotteryToken; // ERC20 contract // isOnlyETHAccepted = _isOnlyETHAccepted; } function pauseNextLottery() public onlyOwner { // require( // msg.sender == adminAddress, // "Starting the Lottery requires Admin Access" // ); pauseLottery = true; emit LotteryPaused(); } function unPauseNextLottery() public onlyOwner { // require( // msg.sender == adminAddress, // "Starting the Lottery requires Admin Access" // ); pauseLottery = false; emit LotteryUnPaused(); // resetLottery(); } function withdrawLink() external onlyOwner { LINK.transfer(owner(), LINK.balanceOf(address(this))); } function changeFeeAddress(address _feeAddress) public onlyOwner { require(_feeAddress != address(0), "Incorrect fee address"); feeAddress = _feeAddress; } /** * @dev Calls ChainLink Oracle's inherited function for * Random Number Generation. * * Requirements: * * - the contract must have a balance of at least `fee` required for VRF. */ function getRandomNumber(uint256 userProvidedSeed) internal returns (bytes32 requestId) { require( LINK.balanceOf(address(this)) >= fee, "Not enough LINK - fill contract with faucet" ); isRandomNumberGenerated = false; return requestRandomness(keyHash, fee, userProvidedSeed); } /** * @dev The callback function of ChainLink Oracle when the * Random Number Generation is completed. An event is fired * to notify the same and the randomResult is saved. * * Emits an {RandomNumberGenerated} event indicating the random number is * generated by the Oracle. * */ function fulfillRandomness(bytes32 requestId, uint256 randomness) internal override { randomResult = randomness; isRandomNumberGenerated = true; emit RandomNumberGenerated(randomness); } /** * @dev Sets the Lottery Config, initializes an instance of * ERC20 contract that the lottery is based on and starts the lottery. * * Emits an {LotteryStarted} event indicating the Admin has started the Lottery. * * Requirements: * * - Cannot be called if the lottery is in progress. * - Only the address set at `adminAddress` can call this function. * - Number of winners `numOfWinners` should be less than or equal to half the number of * players `playersLimit`. */ function setLotteryRules( uint256 numOfWinners, uint256 playersLimit, uint256 registrationAmount, uint256 adminFeePercentage, uint256 randomSeed ) public onlyOwner { // require( // msg.sender == adminAddress, // "Starting the Lottery requires Admin Access" // ); require( lotteryStatus == LotteryStatus.NOTSTARTED, "Error: An existing lottery is in progress" ); require( numOfWinners <= playersLimit.div(2), "Number of winners should be less than or equal to half the number of players" ); lotteryConfig = LotteryConfig( numOfWinners, playersLimit, registrationAmount, adminFeePercentage, // lotteryTokenAddress, randomSeed, block.timestamp ); lotteryStatus = LotteryStatus.INPROGRESS; loserLotteryAmount = (registrationAmount.mul(1e18)).div( 10**buyToken.decimals() ); emit LotteryStarted( // lotteryTokenAddress, playersLimit, numOfWinners, registrationAmount, block.timestamp ); } /** * @dev Player enters the lottery and the registration amount is * transferred from the player to the contract. * * Returns participant's index. This is similar to unique registration id. * Emits an {MaxParticipationCompleted} event indicating that all the required players have entered the lottery. * * The participant is also issued an equal amount of LOT tokens once he registers for the lottery. * This LOT tokens are fundamental to the lottery contract and are used internally. * The winners will need to burn their LOT tokens to claim the lottery winnings. * The other participants of the lottery can keep hold of these tokens and use for other applications. * * Requirements: * * - The player has set the necessary allowance to the Contract. * - The Lottery is in progress. * - Number of players allowed to enter in the lottery should be * less than or equal to the allowed players `lotteryConfig.playersLimit`. */ function enterLottery() public returns (uint256) { require( lotteryPlayers.length < lotteryConfig.playersLimit, "Max Participation for the Lottery Reached" ); // require( // lotteryPlayers.length == 0 && !pauseLottery, // "Lottery is paused" // ); if (lotteryPlayers.length == 0) { require(!pauseLottery, "Lottery is paused"); } require( lotteryStatus == LotteryStatus.INPROGRESS, "The Lottery is not started or closed" ); lotteryPlayers.push(msg.sender); buyToken.transferFrom( msg.sender, address(this), lotteryConfig.registrationAmount ); totalLotteryPool = totalLotteryPool.add( lotteryConfig.registrationAmount ); // call _mint from constructor ERC20 // Not giving loser lottery tokens !! // lotteryToken.mint(msg.sender, lotteryConfig.registrationAmount); if (lotteryPlayers.length == lotteryConfig.playersLimit) { // emit MaxParticipationCompleted(msg.sender); // this is not needed now getRandomNumber(lotteryConfig.randomSeed); } return (lotteryPlayers.length).sub(1); } /** * @dev Settles the lottery, the winners are calculated based on * the random number generated. The Admin fee is calculated and * transferred back to Admin `adminAddress`. * * Emits an {WinnersGenerated} event indicating that the winners for the lottery have been generated. * Emits {LotterySettled} event indicating that the winnings have been transferred to the Admin and the Lottery is closed. * * Requirements: * * - The random number has been generated * - The Lottery is in progress. */ function settleLottery() external { require( isRandomNumberGenerated, "Lottery Configuration still in progress. Please try in a short while" ); require( lotteryStatus == LotteryStatus.INPROGRESS, "The Lottery is not started or closed" ); for (uint256 i = 0; i < lotteryConfig.numOfWinners; i = i.add(1)) { uint256 winningIndex = randomResult.mod(lotteryConfig.playersLimit); uint256 counter = 0; while (winnerAddresses[winningIndex] != address(0)) { randomResult = getRandomNumberBlockchain(i, randomResult); winningIndex = randomResult.mod(lotteryConfig.playersLimit); counter = counter.add(1); if (counter == lotteryConfig.playersLimit) { while (winnerAddresses[winningIndex] != address(0)) { winningIndex = (winningIndex.add(1)).mod( lotteryConfig.playersLimit ); } counter = 0; } } winnerAddresses[winningIndex] = lotteryPlayers[winningIndex]; winnerIndexes.push(winningIndex); randomResult = getRandomNumberBlockchain(i, randomResult); } areWinnersGenerated = true; emit WinnersGenerated(winnerIndexes); adminFeesAmount = ( (totalLotteryPool.mul(lotteryConfig.adminFeePercentage)).div(100) ); rewardPoolAmount = (totalLotteryPool.sub(adminFeesAmount)).div( lotteryConfig.numOfWinners ); lotteryStatus = LotteryStatus.CLOSED; // if (isOnlyETHAccepted) { // (bool status, ) = payable(adminAddress).call{ // value: adminFeesAmount // }(""); // require(status, "Admin fees not transferred"); // } else { buyToken.transfer(feeAddress, adminFeesAmount); // } emit LotterySettled( rewardPoolAmount, lotteryConfig.numOfWinners, adminFeesAmount ); collectRewards(); } function getWinningAmount() public view returns (uint256) { uint256 expectedTotalLotteryPool = lotteryConfig.playersLimit.mul( lotteryConfig.registrationAmount ); uint256 adminFees = ( (expectedTotalLotteryPool.mul(lotteryConfig.adminFeePercentage)) .div(100) ); uint256 rewardPool = (expectedTotalLotteryPool.sub(adminFees)).div( lotteryConfig.numOfWinners ); return rewardPool; } function getCurrentlyActivePlayers() public view returns (uint256) { return lotteryPlayers.length; } /** * @dev The winners of the lottery can call this function to transfer their winnings * from the lottery contract to their own address. The winners will need to burn their * LOT tokens to claim the lottery rewards. This is executed by the lottery contract itself. * * * Requirements: * * - The Lottery is settled i.e. the lotteryStatus is CLOSED. */ /** * @dev The winners of the lottery can call this function to transfer their winnings * from the lottery contract to their own address. The winners will need to burn their * LOT tokens to claim the lottery rewards. This is executed by the lottery contract itself. * * * Requirements: * * - The Lottery is settled i.e. the lotteryStatus is CLOSED. */ function collectRewards() private nonReentrant { // require( // lotteryStatus == LotteryStatus.CLOSED, // "The Lottery is not settled. Please try in a short while." // ); bool isWinner = false; for (uint256 i = 0; i < lotteryConfig.playersLimit; i = i.add(1)) { address player = lotteryPlayers[i]; // if (address(msg.sender) == winnerAddresses[winnerIndexes[i]]) { for (uint256 j = 0; j < lotteryConfig.numOfWinners; j = j.add(1)) { address winner = winnerAddresses[winnerIndexes[j]]; if (winner != address(0) && winner == player) { isWinner = true; winnerAddresses[winnerIndexes[j]] = address(0); break; } } if (isWinner) { // _burn(address(msg.sender), lotteryConfig.registrationAmount); // lotteryToken.burnFrom(msg.sender, lotteryConfig.registrationAmount); // if (isOnlyETHAccepted) { // (bool status, ) = payable(player).call{ // value: rewardPoolAmount // }(""); // require(status, "Amount not transferred to winner"); // } else { buyToken.transfer(address(player), rewardPoolAmount); // } } else { lotteryToken.mint(player, loserLotteryAmount); } isWinner = false; } resetLottery(); } /** * @dev Generates a random number based on the blockHash and random offset */ function getRandomNumberBlockchain(uint256 offset, uint256 randomness) internal view returns (uint256) { bytes32 offsetBlockhash = blockhash(block.number.sub(offset)); uint256 randomBlockchainNumber = uint256(offsetBlockhash); uint256 finalRandomNumber = randomness + randomBlockchainNumber; if (finalRandomNumber >= randomness) { return finalRandomNumber; } else { if (randomness >= randomBlockchainNumber) { return randomness.sub(randomBlockchainNumber); } return randomBlockchainNumber.sub(randomness); } } /** * It can be called by admin to withdraw all the amount in case of * any failure to play lottery. It will be distributed later on amongst the * participants. */ function emergencyWithdraw() external onlyOwner { buyToken.transfer(msg.sender, buyToken.balanceOf(address(this))); emit EmergencyWithdrawn(); } /** * @dev Resets the lottery, clears the existing state variable values and the lottery * can be initialized again. * * Emits {LotteryReset} event indicating that the lottery config and contract state is reset. * * Requirements: * * - Only the address set at `adminAddress` can call this function. * - The Lottery has closed. */ function resetLottery() private { // require( // msg.sender == adminAddress, // "Resetting the Lottery requires Admin Access" // ); // require( // lotteryStatus == LotteryStatus.CLOSED, // "Lottery Still in Progress" // ); uint256 tokenBalance = lotteryToken.balanceOf(address(this)); if (tokenBalance > 0) { buyToken.transfer(feeAddress, tokenBalance); } // delete lotteryConfig; delete randomResult; lotteryStatus = LotteryStatus.INPROGRESS; delete totalLotteryPool; delete adminFeesAmount; delete rewardPoolAmount; for (uint256 i = 0; i < lotteryPlayers.length; i = i.add(1)) { delete winnerAddresses[i]; } isRandomNumberGenerated = false; areWinnersGenerated = false; delete winnerIndexes; delete lotteryPlayers; emit LotteryReset(); } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; /** * @dev Interface of the ERC20 standard as defined in the EIP. */ interface IERC20 { /** * @dev Returns the amount of tokens in existence. */ function totalSupply() external view returns (uint256); /** * @dev Returns the amount of tokens owned by `account`. */ function balanceOf(address account) external view returns (uint256); /** * @dev Moves `amount` tokens from the caller's account to `recipient`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address recipient, uint256 amount) external returns (bool); /** * @dev Returns the remaining number of tokens that `spender` will be * allowed to spend on behalf of `owner` through {transferFrom}. This is * zero by default. * * This value changes when {approve} or {transferFrom} are called. */ function allowance(address owner, address spender) external view returns (uint256); /** * @dev Sets `amount` as the allowance of `spender` over the caller's tokens. * * Returns a boolean value indicating whether the operation succeeded. * * IMPORTANT: Beware that changing an allowance with this method brings the risk * that someone may use both the old and the new allowance by unfortunate * transaction ordering. One possible solution to mitigate this race * condition is to first reduce the spender's allowance to 0 and set the * desired value afterwards: * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729 * * Emits an {Approval} event. */ function approve(address spender, uint256 amount) external returns (bool); function mint(address receipient, uint256 amount) external returns (bool); function burnFrom(address from, uint256 amount) external; function decimals() external view returns (uint256); /** * @dev Moves `amount` tokens from `sender` to `recipient` using the * allowance mechanism. `amount` is then deducted from the caller's * allowance. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transferFrom( address sender, address recipient, uint256 amount ) external returns (bool); /** * @dev Emitted when `value` tokens are moved from one account (`from`) to * another (`to`). * * Note that `value` may be zero. */ event Transfer(address indexed from, address indexed to, uint256 value); /** * @dev Emitted when the allowance of a `spender` for an `owner` is set by * a call to {approve}. `value` is the new allowance. */ event Approval( address indexed owner, address indexed spender, uint256 value ); }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.0; import "@openzeppelin/contracts/math/SafeMath.sol"; 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 constuctor(<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 { using SafeMath for uint256; /** * @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; /** * @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 * @param _seed seed mixed into the input of the VRF. * * @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, uint256 _seed) internal returns (bytes32 requestId) { LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, _seed)); // 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, _seed, 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].add(1); return makeRequestId(_keyHash, vRFSeed); } LinkTokenInterface immutable internal LINK; address immutable private vrfCoordinator; // Nonces for each VRF key from which randomness has been requested. // // Must stay in sync with VRFCoordinator[_keyHash][this] mapping(bytes32 /* keyHash */ => uint256 /* 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) public { 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); } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.2 <0.8.0; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize, which returns 0 for contracts in // construction, since the code is only stored at the end of the // constructor execution. uint256 size; // solhint-disable-next-line no-inline-assembly assembly { size := extcodesize(account) } return size > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); // solhint-disable-next-line avoid-low-level-calls, avoid-call-value (bool success, ) = recipient.call{ value: amount }(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain`call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue(address target, bytes memory data, uint256 value, string memory errorMessage) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.call{ value: value }(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data, string memory errorMessage) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.staticcall(data); return _verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data, string memory errorMessage) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); // solhint-disable-next-line avoid-low-level-calls (bool success, bytes memory returndata) = target.delegatecall(data); return _verifyCallResult(success, returndata, errorMessage); } function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly // solhint-disable-next-line no-inline-assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor () internal { address msgSender = _msgSender(); _owner = msgSender; emit OwnershipTransferred(address(0), msgSender); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { emit OwnershipTransferred(_owner, address(0)); _owner = address(0); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); emit OwnershipTransferred(_owner, newOwner); _owner = newOwner; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor () internal { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and make it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0 <0.8.0; /** * @dev Wrappers over Solidity's arithmetic operations with added overflow * checks. * * Arithmetic operations in Solidity wrap on overflow. This can easily result * in bugs, because programmers usually assume that an overflow raises an * error, which is the standard behavior in high level programming languages. * `SafeMath` restores this intuition by reverting the transaction when an * operation overflows. * * Using this library instead of the unchecked operations eliminates an entire * class of bugs, so it's recommended to use it always. */ library SafeMath { /** * @dev Returns the addition of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) { uint256 c = a + b; if (c < a) return (false, 0); return (true, c); } /** * @dev Returns the substraction of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b > a) return (false, 0); return (true, a - b); } /** * @dev Returns the multiplication of two unsigned integers, with an overflow flag. * * _Available since v3.4._ */ function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) { // Gas optimization: this is cheaper than requiring 'a' not being zero, but the // benefit is lost if 'b' is also tested. // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522 if (a == 0) return (true, 0); uint256 c = a * b; if (c / a != b) return (false, 0); return (true, c); } /** * @dev Returns the division of two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a / b); } /** * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag. * * _Available since v3.4._ */ function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) { if (b == 0) return (false, 0); return (true, a % b); } /** * @dev Returns the addition of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `+` operator. * * Requirements: * * - Addition cannot overflow. */ function add(uint256 a, uint256 b) internal pure returns (uint256) { uint256 c = a + b; require(c >= a, "SafeMath: addition overflow"); return c; } /** * @dev Returns the subtraction of two unsigned integers, reverting on * overflow (when the result is negative). * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b) internal pure returns (uint256) { require(b <= a, "SafeMath: subtraction overflow"); return a - b; } /** * @dev Returns the multiplication of two unsigned integers, reverting on * overflow. * * Counterpart to Solidity's `*` operator. * * Requirements: * * - Multiplication cannot overflow. */ function mul(uint256 a, uint256 b) internal pure returns (uint256) { if (a == 0) return 0; uint256 c = a * b; require(c / a == b, "SafeMath: multiplication overflow"); return c; } /** * @dev Returns the integer division of two unsigned integers, reverting on * division by zero. The result is rounded towards zero. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: division by zero"); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting when dividing by zero. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b) internal pure returns (uint256) { require(b > 0, "SafeMath: modulo by zero"); return a % b; } /** * @dev Returns the subtraction of two unsigned integers, reverting with custom message on * overflow (when the result is negative). * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {trySub}. * * Counterpart to Solidity's `-` operator. * * Requirements: * * - Subtraction cannot overflow. */ function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b <= a, errorMessage); return a - b; } /** * @dev Returns the integer division of two unsigned integers, reverting with custom message on * division by zero. The result is rounded towards zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryDiv}. * * Counterpart to Solidity's `/` operator. Note: this function uses a * `revert` opcode (which leaves remaining gas untouched) while Solidity * uses an invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a / b; } /** * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo), * reverting with custom message when dividing by zero. * * CAUTION: This function is deprecated because it requires allocating memory for the error * message unnecessarily. For custom revert reasons use {tryMod}. * * Counterpart to Solidity's `%` operator. This function uses a `revert` * opcode (which leaves remaining gas untouched) while Solidity uses an * invalid opcode to revert (consuming all remaining gas). * * Requirements: * * - The divisor cannot be zero. */ function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) { require(b > 0, errorMessage); return a % b; } }
// SPDX-License-Identifier: MIT pragma solidity ^0.6.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.6.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.6.0 <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 GSN 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 payable) { return msg.sender; } function _msgData() internal view virtual returns (bytes memory) { this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691 return msg.data; } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "abi" ] } }, "libraries": {} }
Contract Security Audit
- No Contract Security Audit Submitted- Submit Audit Here
[{"inputs":[{"internalType":"contract IERC20","name":"_buyToken","type":"address"},{"internalType":"contract IERC20","name":"_lotteryToken","type":"address"},{"internalType":"address","name":"_feeAddress","type":"address"},{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"bytes32","name":"_keyHash","type":"bytes32"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[],"name":"EmergencyWithdrawn","type":"event"},{"anonymous":false,"inputs":[],"name":"LotteryPaused","type":"event"},{"anonymous":false,"inputs":[],"name":"LotteryReset","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_rewardPoolAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_players","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"_adminFees","type":"uint256"}],"name":"LotterySettled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"playersLimit","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numOfWinners","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"registrationAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startedAt","type":"uint256"}],"name":"LotteryStarted","type":"event"},{"anonymous":false,"inputs":[],"name":"LotteryUnPaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"RandomNumberGenerated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256[]","name":"winnerIndexes","type":"uint256[]"}],"name":"WinnersGenerated","type":"event"},{"inputs":[],"name":"adminFeesAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"buyToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_feeAddress","type":"address"}],"name":"changeFeeAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"enterLottery","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"feeAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentlyActivePlayers","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getWinningAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"loserLotteryAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lotteryConfig","outputs":[{"internalType":"uint256","name":"numOfWinners","type":"uint256"},{"internalType":"uint256","name":"playersLimit","type":"uint256"},{"internalType":"uint256","name":"registrationAmount","type":"uint256"},{"internalType":"uint256","name":"adminFeePercentage","type":"uint256"},{"internalType":"uint256","name":"randomSeed","type":"uint256"},{"internalType":"uint256","name":"startedAt","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"lotteryPlayers","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lotteryStatus","outputs":[{"internalType":"enum LotteryContract.LotteryStatus","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lotteryToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseLottery","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseNextLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"rewardPoolAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numOfWinners","type":"uint256"},{"internalType":"uint256","name":"playersLimit","type":"uint256"},{"internalType":"uint256","name":"registrationAmount","type":"uint256"},{"internalType":"uint256","name":"adminFeePercentage","type":"uint256"},{"internalType":"uint256","name":"randomSeed","type":"uint256"}],"name":"setLotteryRules","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"settleLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"totalLotteryPool","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unPauseNextLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"winnerAddresses","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"winnerIndexes","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdrawLink","outputs":[],"stateMutability":"nonpayable","type":"function"}]
Contract Creation Code
60c060405234801561001057600080fd5b506040516121ec3803806121ec833981810160405260c081101561003357600080fd5b5080516020820151604083015160608085015160808087015160a0978801516001600160601b031984861b81169099529381901b90971690526001805593949293919290600061008161013a565b600280546001600160a01b0319166001600160a01b038316908117909155604051919250906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350600480546001600160a01b039586166001600160a01b031991821617909155600b80546000600755601293909355655af3107a40006013556015805461ffff191690556001600160a81b03199092169685169690961790555050600a8054909316911617905561013e565b3390565b60805160601c60a05160601c61207161017b60003980610c165280611c76525080610ab85280610b0d528061199b5280611c4752506120716000f3fe608060405234801561001057600080fd5b50600436106101a95760003560e01c80638dc654a2116100f9578063c1af578511610097578063f2fde38b11610071578063f2fde38b1461032e578063f9b93a1d14610354578063fc5ab87c14610371578063fdce40d3146103ac576101a9565b8063c1af578514610301578063cd843b7714610309578063db2e21bc14610326576101a9565b8063a4821719116100d3578063a4821719146102cd578063ab73e144146102d5578063ae97f5fd146102f1578063bb7152a7146102f9576101a9565b80638dc654a21461029a57806394539467146102a257806394985ddd146102aa576101a9565b806353b52215116101665780635bfd0af6116101405780635bfd0af61461027a5780636dad2a9114610282578063715018a61461028a5780638da5cb5b14610292576101a9565b806353b522151461026257806358509f2f1461026a5780635ad726b414610272576101a9565b806303b604f4146101ae578063045f9c97146101b85780630d683dd9146101f1578063285e14061461021a57806341275358146102405780635268cd9314610248575b600080fd5b6101b66103e1565b005b6101d5600480360360208110156101ce57600080fd5b503561047a565b604080516001600160a01b039092168252519081900360200190f35b6101f9610495565b6040518082600281111561020957fe5b815260200191505060405180910390f35b6101b66004803603602081101561023057600080fd5b50356001600160a01b03166104a5565b6101d561057c565b61025061058b565b60408051918252519081900360200190f35b610250610591565b610250610597565b6101b661059d565b61025061093f565b610250610945565b6101b6610999565b6101d5610a45565b6101b6610a54565b6101d5610bfc565b6101b6600480360360408110156102c057600080fd5b5080359060200135610c0b565b6101d5610c92565b6102dd610ca1565b604080519115158252519081900360200190f35b610250610cb0565b6101b6610cb6565b610250610d54565b6102506004803603602081101561031f57600080fd5b5035610f58565b6101b6610f76565b6101b66004803603602081101561034457600080fd5b50356001600160a01b03166110fe565b6101d56004803603602081101561036a57600080fd5b5035611201565b610379611228565b604080519687526020870195909552858501939093526060850191909152608084015260a0830152519081900360c00190f35b6101b6600480360360a08110156103c257600080fd5b508035906020810135906040810135906060810135906080013561123d565b6103e9611474565b6001600160a01b03166103fa610a45565b6001600160a01b031614610443576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6015805462ff0000191690556040517f6b696c23438b6736443b11696dd8279c0189de0e47d44803ce815621e396083190600090a1565b6005602052600090815260409020546001600160a01b031681565b600b54600160a01b900460ff1681565b6104ad611474565b6001600160a01b03166104be610a45565b6001600160a01b031614610507576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6001600160a01b03811661055a576040805162461bcd60e51b8152602060048201526015602482015274496e636f727265637420666565206164647265737360581b604482015290519081900360640190fd5b600480546001600160a01b0319166001600160a01b0392909216919091179055565b6004546001600160a01b031681565b60085481565b60035490565b60165481565b601554610100900460ff166105e35760405162461bcd60e51b8152600401808060200182810382526044815260200180611ff86044913960600191505060405180910390fd5b6001600b54600160a01b900460ff1660028111156105fd57fe5b146106395760405162461bcd60e51b8152600401808060200182810382526024815260200180611fd46024913960400191505060405180910390fd5b60005b600c5481101561079457600d546014546000916106599190611478565b905060005b6000828152600560205260409020546001600160a01b0316156106f957610687836014546114e1565b6014819055600d546106999190611478565b91506106a681600161152b565b600d549091508114156106f4575b6000828152600560205260409020546001600160a01b0316156106f057600d546106e9906106e384600161152b565b90611478565b91506106b4565b5060005b61065e565b6003828154811061070657fe5b600091825260208083209091015484835260059091526040822080546001600160a01b0319166001600160a01b039092169190911790556006805460018101825591527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0182905560145461077c9084906114e1565b6014555061078d905081600161152b565b905061063c565b506015805460ff19166001179055604080516020808252600680549183018290527fa13f7b4dbc201a7d6c6a72975f8f690748efea2d6504de79984ffeee6973c6059390929182918201908490801561080c57602002820191906000526020600020905b8154815260200190600101908083116107f8575b50509250505060405180910390a1600f54600754610836916064916108309161158c565b906115e5565b6008819055600c5460075461084f92610830919061164c565b600955600b805460ff60a01b1916600160a11b1790819055600480546008546040805163a9059cbb60e01b81526001600160a01b039384169481019490945260248401919091525192169163a9059cbb916044808201926020929091908290030181600087803b1580156108c257600080fd5b505af11580156108d6573d6000803e3d6000fd5b505050506040513d60208110156108ec57600080fd5b5050600954600c5460085460408051938452602084019290925282820152517f782c72f86b2d0a9b6d7639cb60b06064c5b3f21796fde3d2cda7ba94a8eb02d79181900360600190a161093d6116a9565b565b60095481565b600e54600d5460009182916109599161158c565b9050600061097a6064610830600c600301548561158c90919063ffffffff16565b600c5490915060009061099190610830858561164c565b935050505090565b6109a1611474565b6001600160a01b03166109b2610a45565b6001600160a01b0316146109fb576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6002546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600280546001600160a01b0319169055565b6002546001600160a01b031690565b610a5c611474565b6001600160a01b0316610a6d610a45565b6001600160a01b031614610ab6576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b7f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031663a9059cbb610aed610a45565b604080516370a0823160e01b815230600482015290516001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016916370a08231916024808301926020929190829003018186803b158015610b5357600080fd5b505afa158015610b67573d6000803e3d6000fd5b505050506040513d6020811015610b7d57600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b158015610bce57600080fd5b505af1158015610be2573d6000803e3d6000fd5b505050506040513d6020811015610bf857600080fd5b5050565b600a546001600160a01b031681565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610c88576040805162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c00604482015290519081900360640190fd5b610bf88282611951565b600b546001600160a01b031681565b60155462010000900460ff1681565b60075481565b610cbe611474565b6001600160a01b0316610ccf610a45565b6001600160a01b031614610d18576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6015805462ff00001916620100001790556040517fc1a06552b071d5308a563af238d8ac7d9bf3a311d71ee8e7add408f9209404fe90600090a1565b600d5460035460009111610d995760405162461bcd60e51b8152600401808060200182810382526029815260200180611f6a6029913960400191505060405180910390fd5b600354610df25760155462010000900460ff1615610df2576040805162461bcd60e51b8152602060048201526011602482015270131bdd1d195c9e481a5cc81c185d5cd959607a1b604482015290519081900360640190fd5b6001600b54600160a01b900460ff166002811115610e0c57fe5b14610e485760405162461bcd60e51b8152600401808060200182810382526024815260200180611fd46024913960400191505060405180910390fd5b6003805460018101825560009182527fc2575a0e9e593c00f959f8c92f12db2869c3395a3b0502d05e2516446f71f85b0180546001600160a01b03191633908117909155600b54600e54604080516323b872dd60e01b815260048101949094523060248501526044840191909152516001600160a01b0391909116926323b872dd92606480820193602093909283900390910190829087803b158015610eed57600080fd5b505af1158015610f01573d6000803e3d6000fd5b505050506040513d6020811015610f1757600080fd5b5050600e54600754610f289161152b565b600755600d546003541415610f4557601054610f4390611994565b505b600354610f5390600161164c565b905090565b60068181548110610f6557fe5b600091825260209091200154905081565b610f7e611474565b6001600160a01b0316610f8f610a45565b6001600160a01b031614610fd8576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b600b54604080516370a0823160e01b815230600482015290516001600160a01b039092169163a9059cbb91339184916370a08231916024808301926020929190829003018186803b15801561102c57600080fd5b505afa158015611040573d6000803e3d6000fd5b505050506040513d602081101561105657600080fd5b5051604080516001600160e01b031960e086901b1681526001600160a01b03909316600484015260248301919091525160448083019260209291908290030181600087803b1580156110a757600080fd5b505af11580156110bb573d6000803e3d6000fd5b505050506040513d60208110156110d157600080fd5b50506040517fcd310f174a338d5afb2b17ebca2bda872a317a1e5ec53f6277803b93e8644eb990600090a1565b611106611474565b6001600160a01b0316611117610a45565b6001600160a01b031614611160576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6001600160a01b0381166111a55760405162461bcd60e51b8152600401808060200182810382526026815260200180611ea46026913960400191505060405180910390fd5b6002546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600280546001600160a01b0319166001600160a01b0392909216919091179055565b6003818154811061120e57fe5b6000918252602090912001546001600160a01b0316905081565b600c54600d54600e54600f5460105460115486565b611245611474565b6001600160a01b0316611256610a45565b6001600160a01b03161461129f576040805162461bcd60e51b81526020600482018190526024820152600080516020611fb4833981519152604482015290519081900360640190fd5b6000600b54600160a01b900460ff1660028111156112b957fe5b146112f55760405162461bcd60e51b8152600401808060200182810382526029815260200180611eca6029913960400191505060405180910390fd5b6113008460026115e5565b85111561133e5760405162461bcd60e51b815260040180806020018281038252604c815260200180611f1e604c913960600191505060405180910390fd5b6040805160c081018252868152602080820187905281830186905260608201859052608082018490524260a0909201829052600c889055600d879055600e869055600f8590556010849055601191909155600b805460ff60a01b1916600160a01b1790819055825163313ce56760e01b81529251611424936001600160a01b039092169263313ce5679260048181019391829003018186803b1580156113e357600080fd5b505afa1580156113f7573d6000803e3d6000fd5b505050506040513d602081101561140d57600080fd5b5051600a0a61083085670de0b6b3a764000061158c565b601655604080518581526020810187905280820185905242606082015290517fce72aaaa67c222d8ec98e00408e79a7eadb369594351a5a7d7fec6609d108ba29181900360800190a15050505050565b3390565b60008082116114ce576040805162461bcd60e51b815260206004820152601860248201527f536166654d6174683a206d6f64756c6f206279207a65726f0000000000000000604482015290519081900360640190fd5b8183816114d757fe5b0690505b92915050565b6000806114ee438561164c565b409050808381018481106115065792506114db915050565b81851061152157611517858361164c565b93505050506114db565b611517828661164c565b600082820183811015611585576040805162461bcd60e51b815260206004820152601b60248201527f536166654d6174683a206164646974696f6e206f766572666c6f770000000000604482015290519081900360640190fd5b9392505050565b60008261159b575060006114db565b828202828482816115a857fe5b04146115855760405162461bcd60e51b8152600401808060200182810382526021815260200180611f936021913960400191505060405180910390fd5b600080821161163b576040805162461bcd60e51b815260206004820152601a60248201527f536166654d6174683a206469766973696f6e206279207a65726f000000000000604482015290519081900360640190fd5b81838161164457fe5b049392505050565b6000828211156116a3576040805162461bcd60e51b815260206004820152601e60248201527f536166654d6174683a207375627472616374696f6e206f766572666c6f770000604482015290519081900360640190fd5b50900390565b60026001541415611701576040805162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604482015290519081900360640190fd5b60026001556000805b600d548110156119415760006003828154811061172357fe5b60009182526020822001546001600160a01b031691505b600c54811015611810576000600560006006848154811061175757fe5b600091825260208083209091015483528201929092526040019020546001600160a01b03169050801580159061179e5750826001600160a01b0316816001600160a01b0316145b156117fd5760019450600060056000600685815481106117ba57fe5b9060005260206000200154815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b0316021790555050611810565b5061180981600161152b565b905061173a565b5082156118a357600b546009546040805163a9059cbb60e01b81526001600160a01b03858116600483015260248201939093529051919092169163a9059cbb9160448083019260209291908290030181600087803b15801561187157600080fd5b505af1158015611885573d6000803e3d6000fd5b505050506040513d602081101561189b57600080fd5b5061192a9050565b600a54601654604080516340c10f1960e01b81526001600160a01b0385811660048301526024820193909352905191909216916340c10f199160448083019260209291908290030181600087803b1580156118fd57600080fd5b505af1158015611911573d6000803e3d6000fd5b505050506040513d602081101561192757600080fd5b50505b506000915061193a81600161152b565b905061170a565b5061194a611a8b565b5060018055565b60148190556015805461ff00191661010017905560405181907facb85192b17e57cdd6ffdc2af021cc70c3a2269771b37b82dd36695fec903af590600090a25050565b60006013547f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03166370a08231306040518263ffffffff1660e01b815260040180826001600160a01b0316815260200191505060206040518083038186803b158015611a0657600080fd5b505afa158015611a1a573d6000803e3d6000fd5b505050506040513d6020811015611a3057600080fd5b50511015611a6f5760405162461bcd60e51b815260040180806020018281038252602b815260200180611ef3602b913960400191505060405180910390fd5b6015805461ff00191690556012546013546114db919084611c43565b600a54604080516370a0823160e01b815230600482015290516000926001600160a01b0316916370a08231916024808301926020929190829003018186803b158015611ad657600080fd5b505afa158015611aea573d6000803e3d6000fd5b505050506040513d6020811015611b0057600080fd5b505190508015611b9157600b54600480546040805163a9059cbb60e01b81526001600160a01b0392831693810193909352602483018590525192169163a9059cbb916044808201926020929091908290030181600087803b158015611b6457600080fd5b505af1158015611b78573d6000803e3d6000fd5b505050506040513d6020811015611b8e57600080fd5b50505b60006014819055600b805460ff60a01b1916600160a01b1790556007819055600881905560098190555b600354811015611bf357600081815260056020526040902080546001600160a01b0319169055611bec81600161152b565b9050611bbb565b506015805461ffff19169055611c0b60066000611e69565b611c1760036000611e69565b6040517fc07cdc0437f4a5523d938e3a96f2e751ce4a8e8784c5ce2316c7f833ac26772090600090a150565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000085878660405160200180838152602001828152602001925050506040516020818303038152906040526040518463ffffffff1660e01b815260040180846001600160a01b0316815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015611d1f578181015183820152602001611d07565b50505050905090810190601f168015611d4c5780820380516001836020036101000a031916815260200191505b50945050505050602060405180830381600087803b158015611d6d57600080fd5b505af1158015611d81573d6000803e3d6000fd5b505050506040513d6020811015611d9757600080fd5b5050600084815260208190526040812054611db790869085903090611df6565b600086815260208190526040902054909150611dd490600161152b565b600086815260208190526040902055611ded8582611e3d565b95945050505050565b60408051602080820196909652808201949094526001600160a01b039290921660608401526080808401919091528151808403909101815260a09092019052805191012090565b604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b5080546000825590600052602060002090810190611e879190611e8a565b50565b5b80821115611e9f5760008155600101611e8b565b509056fe4f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734572726f723a20416e206578697374696e67206c6f747465727920697320696e2070726f67726573734e6f7420656e6f756768204c494e4b202d2066696c6c20636f6e74726163742077697468206661756365744e756d626572206f662077696e6e6572732073686f756c64206265206c657373207468616e206f7220657175616c20746f2068616c6620746865206e756d626572206f6620706c61796572734d61782050617274696369706174696f6e20666f7220746865204c6f74746572792052656163686564536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572546865204c6f7474657279206973206e6f742073746172746564206f7220636c6f7365644c6f747465727920436f6e66696775726174696f6e207374696c6c20696e2070726f67726573732e20506c656173652074727920696e20612073686f7274207768696c65a26469706673582212207c38cd001e2b9673d82e02aa35277b5c2ae3b8f3f400d09dd0a34bb6060fc82e64736f6c634300060c00330000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000b032512a23ef041bec2e48e9b3f07286408b2b26000000000000000000000000445c96b55e6846a039f90ed21f979afebd2392d60000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1f86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174000000000000000000000000b032512a23ef041bec2e48e9b3f07286408b2b26000000000000000000000000445c96b55e6846a039f90ed21f979afebd2392d60000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1f86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da
-----Decoded View---------------
Arg [0] : _buyToken (address): 0x2791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [1] : _lotteryToken (address): 0xb032512a23ef041bec2e48e9b3f07286408b2b26
Arg [2] : _feeAddress (address): 0x445c96b55e6846a039f90ed21f979afebd2392d6
Arg [3] : _vrfCoordinator (address): 0x3d2341adb2d31f1c5530cdc622016af293177ae0
Arg [4] : _link (address): 0xb0897686c545045afc77cf20ec7a532e3120e0f1
Arg [5] : _keyHash (bytes32): 0xf86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da
-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000002791bca1f2de4661ed88a30c99a7a9449aa84174
Arg [1] : 000000000000000000000000b032512a23ef041bec2e48e9b3f07286408b2b26
Arg [2] : 000000000000000000000000445c96b55e6846a039f90ed21f979afebd2392d6
Arg [3] : 0000000000000000000000003d2341adb2d31f1c5530cdc622016af293177ae0
Arg [4] : 000000000000000000000000b0897686c545045afc77cf20ec7a532e3120e0f1
Arg [5] : f86195cf7690c55907b2b611ebb7343a6f649bff128701cc542f0569e2c549da
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|
Make sure to use the "Vote Down" button for any spammy posts, and the "Vote Up" for interesting conversations.