Contract Overview
Balance:
0 MATIC
Token:
My Name Tag:
Not Available
[ Download CSV Export ]
Contract Name:
PancakeSwapLottery
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: MIT pragma solidity ^0.8.4; pragma abicoder v2; import "@openzeppelin/contracts/access/Ownable.sol"; import "@openzeppelin/contracts/security/ReentrancyGuard.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "./interfaces/IRandomNumberGenerator.sol"; import "./interfaces/IPancakeSwapLottery.sol"; /** @title PancakeSwap Lottery. * @notice It is a contract for a lottery system using * randomness provided externally. */ contract PancakeSwapLottery is ReentrancyGuard, IPancakeSwapLottery, Ownable { using SafeERC20 for IERC20; address public injectorAddress; address public operatorAddress; address public treasuryAddress; uint256 public currentLotteryId; uint256 public currentTicketId; uint256 public maxNumberTicketsPerBuyOrClaim = 100; uint256 public maxPriceTicketInCake = 50 ether; uint256 public minPriceTicketInCake = 0.005 ether; uint256 public pendingInjectionNextLottery; uint256 public constant MIN_DISCOUNT_DIVISOR = 300; uint256 public constant MIN_LENGTH_LOTTERY = 5 minutes; // 4 hours uint256 public constant MAX_LENGTH_LOTTERY = 4 days + 5 minutes; // 4 days uint256 public constant MAX_TREASURY_FEE = 3000; // 30% IERC20 public cakeToken; IRandomNumberGenerator public randomGenerator; enum Status { Pending, Open, Close, Claimable } struct Lottery { Status status; uint256 startTime; uint256 endTime; uint256 priceTicketInCake; uint256 discountDivisor; uint256[6] rewardsBreakdown; // 0: 1 matching number // 5: 6 matching numbers uint256 treasuryFee; // 500: 5% // 200: 2% // 50: 0.5% uint256[6] cakePerBracket; uint256[6] countWinnersPerBracket; uint256 firstTicketId; uint256 firstTicketIdNextLottery; uint256 amountCollectedInCake; uint32 finalNumber; } struct Ticket { uint32 number; address owner; } // Mapping are cheaper than arrays mapping(uint256 => Lottery) private _lotteries; mapping(uint256 => Ticket) private _tickets; // Bracket calculator is used for verifying claims for ticket prizes mapping(uint32 => uint32) private _bracketCalculator; // Keeps track of number of ticket per unique combination for each lotteryId mapping(uint256 => mapping(uint32 => uint256)) private _numberTicketsPerLotteryId; // Keep track of user ticket ids for a given lotteryId mapping(address => mapping(uint256 => uint256[])) private _userTicketIdsPerLotteryId; modifier notContract() { require(!_isContract(msg.sender), "Contract not allowed"); require(msg.sender == tx.origin, "Proxy contract not allowed"); _; } modifier onlyOperator() { require(msg.sender == operatorAddress, "Not operator"); _; } modifier onlyOwnerOrInjector() { require((msg.sender == owner()) || (msg.sender == injectorAddress), "Not owner or injector"); _; } event AdminTokenRecovery(address token, uint256 amount); event LotteryClose(uint256 indexed lotteryId, uint256 firstTicketIdNextLottery); event LotteryInjection(uint256 indexed lotteryId, uint256 injectedAmount); event LotteryOpen( uint256 indexed lotteryId, uint256 startTime, uint256 endTime, uint256 priceTicketInCake, uint256 firstTicketId, uint256 injectedAmount ); event LotteryNumberDrawn(uint256 indexed lotteryId, uint256 finalNumber, uint256 countWinningTickets); event NewOperatorAndTreasuryAndInjectorAddresses(address operator, address treasury, address injector); event NewRandomGenerator(address indexed randomGenerator); event TicketsPurchase(address indexed buyer, uint256 indexed lotteryId, uint256 numberTickets); event TicketsClaim(address indexed claimer, uint256 amount, uint256 indexed lotteryId, uint256 numberTickets); /** * @notice Constructor * @dev RandomNumberGenerator must be deployed prior to this contract * @param _cakeTokenAddress: address of the CAKE token * @param _randomGeneratorAddress: address of the RandomGenerator contract used to work with ChainLink VRF */ constructor(address _cakeTokenAddress, address _randomGeneratorAddress) { cakeToken = IERC20(_cakeTokenAddress); randomGenerator = IRandomNumberGenerator(_randomGeneratorAddress); // Initializes a mapping _bracketCalculator[0] = 1; _bracketCalculator[1] = 11; _bracketCalculator[2] = 111; _bracketCalculator[3] = 1111; _bracketCalculator[4] = 11111; _bracketCalculator[5] = 111111; } /** * @notice Buy tickets for the current lottery * @param _lotteryId: lotteryId * @param _ticketNumbers: array of ticket numbers between 1,000,000 and 1,999,999 * @dev Callable by users */ function buyTickets(uint256 _lotteryId, uint32[] calldata _ticketNumbers) external override notContract nonReentrant { require(_ticketNumbers.length != 0, "No ticket specified"); require(_ticketNumbers.length <= maxNumberTicketsPerBuyOrClaim, "Too many tickets"); require(_lotteries[_lotteryId].status == Status.Open, "Lottery is not open"); require(block.timestamp < _lotteries[_lotteryId].endTime, "Lottery is over"); // Calculate number of CAKE to this contract uint256 amountCakeToTransfer = _calculateTotalPriceForBulkTickets( _lotteries[_lotteryId].discountDivisor, _lotteries[_lotteryId].priceTicketInCake, _ticketNumbers.length ); // Transfer cake tokens to this contract cakeToken.safeTransferFrom(address(msg.sender), address(this), amountCakeToTransfer); // Increment the total amount collected for the lottery round _lotteries[_lotteryId].amountCollectedInCake += amountCakeToTransfer; for (uint256 i = 0; i < _ticketNumbers.length; i++) { uint32 thisTicketNumber = _ticketNumbers[i]; require((thisTicketNumber >= 1000000) && (thisTicketNumber <= 1999999), "Outside range"); _numberTicketsPerLotteryId[_lotteryId][1 + (thisTicketNumber % 10)]++; _numberTicketsPerLotteryId[_lotteryId][11 + (thisTicketNumber % 100)]++; _numberTicketsPerLotteryId[_lotteryId][111 + (thisTicketNumber % 1000)]++; _numberTicketsPerLotteryId[_lotteryId][1111 + (thisTicketNumber % 10000)]++; _numberTicketsPerLotteryId[_lotteryId][11111 + (thisTicketNumber % 100000)]++; _numberTicketsPerLotteryId[_lotteryId][111111 + (thisTicketNumber % 1000000)]++; _userTicketIdsPerLotteryId[msg.sender][_lotteryId].push(currentTicketId); _tickets[currentTicketId] = Ticket({number: thisTicketNumber, owner: msg.sender}); // Increase lottery ticket number currentTicketId++; } emit TicketsPurchase(msg.sender, _lotteryId, _ticketNumbers.length); } /** * @notice Claim a set of winning tickets for a lottery * @param _lotteryId: lottery id * @param _ticketIds: array of ticket ids * @param _brackets: array of brackets for the ticket ids * @dev Callable by users only, not contract! */ function claimTickets( uint256 _lotteryId, uint256[] calldata _ticketIds, uint32[] calldata _brackets ) external override notContract nonReentrant { require(_ticketIds.length == _brackets.length, "Not same length"); require(_ticketIds.length != 0, "Length must be >0"); require(_ticketIds.length <= maxNumberTicketsPerBuyOrClaim, "Too many tickets"); require(_lotteries[_lotteryId].status == Status.Claimable, "Lottery not claimable"); // Initializes the rewardInCakeToTransfer uint256 rewardInCakeToTransfer; for (uint256 i = 0; i < _ticketIds.length; i++) { require(_brackets[i] < 6, "Bracket out of range"); // Must be between 0 and 5 uint256 thisTicketId = _ticketIds[i]; require(_lotteries[_lotteryId].firstTicketIdNextLottery > thisTicketId, "TicketId too high"); require(_lotteries[_lotteryId].firstTicketId <= thisTicketId, "TicketId too low"); require(msg.sender == _tickets[thisTicketId].owner, "Not the owner"); // Update the lottery ticket owner to 0x address _tickets[thisTicketId].owner = address(0); uint256 rewardForTicketId = _calculateRewardsForTicketId(_lotteryId, thisTicketId, _brackets[i]); // Check user is claiming the correct bracket require(rewardForTicketId != 0, "No prize for this bracket"); if (_brackets[i] != 5) { require( _calculateRewardsForTicketId(_lotteryId, thisTicketId, _brackets[i] + 1) == 0, "Bracket must be higher" ); } // Increment the reward to transfer rewardInCakeToTransfer += rewardForTicketId; } // Transfer money to msg.sender cakeToken.safeTransfer(msg.sender, rewardInCakeToTransfer); emit TicketsClaim(msg.sender, rewardInCakeToTransfer, _lotteryId, _ticketIds.length); } /** * @notice Close lottery * @param _lotteryId: lottery id * @dev Callable by operator */ function closeLottery(uint256 _lotteryId) external override onlyOperator nonReentrant { require(_lotteries[_lotteryId].status == Status.Open, "Lottery not open"); require(block.timestamp > _lotteries[_lotteryId].endTime, "Lottery not over"); _lotteries[_lotteryId].firstTicketIdNextLottery = currentTicketId; // Request a random number from the generator based on a seed randomGenerator.getRandomNumber(uint256(keccak256(abi.encodePacked(_lotteryId, currentTicketId)))); _lotteries[_lotteryId].status = Status.Close; emit LotteryClose(_lotteryId, currentTicketId); } /** * @notice Draw the final number, calculate reward in CAKE per group, and make lottery claimable * @param _lotteryId: lottery id * @param _autoInjection: reinjects funds into next lottery (vs. withdrawing all) * @dev Callable by operator */ function drawFinalNumberAndMakeLotteryClaimable(uint256 _lotteryId, bool _autoInjection) external override onlyOperator nonReentrant { require(_lotteries[_lotteryId].status == Status.Close, "Lottery not close"); require(_lotteryId == randomGenerator.viewLatestLotteryId(), "Numbers not drawn"); // Calculate the finalNumber based on the randomResult generated by ChainLink's fallback uint32 finalNumber = randomGenerator.viewRandomResult(); // Initialize a number to count addresses in the previous bracket uint256 numberAddressesInPreviousBracket; // Calculate the amount to share post-treasury fee uint256 amountToShareToWinners = ( ((_lotteries[_lotteryId].amountCollectedInCake) * (10000 - _lotteries[_lotteryId].treasuryFee)) ) / 10000; // Initializes the amount to withdraw to treasury uint256 amountToWithdrawToTreasury; // Calculate prizes in CAKE for each bracket by starting from the highest one for (uint32 i = 0; i < 6; i++) { uint32 j = 5 - i; uint32 transformedWinningNumber = _bracketCalculator[j] + (finalNumber % (uint32(10)**(j + 1))); _lotteries[_lotteryId].countWinnersPerBracket[j] = _numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber] - numberAddressesInPreviousBracket; // A. If number of users for this _bracket number is superior to 0 if ( (_numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber] - numberAddressesInPreviousBracket) != 0 ) { // B. If rewards at this bracket are > 0, calculate, else, report the numberAddresses from previous bracket if (_lotteries[_lotteryId].rewardsBreakdown[j] != 0) { _lotteries[_lotteryId].cakePerBracket[j] = ((_lotteries[_lotteryId].rewardsBreakdown[j] * amountToShareToWinners) / (_numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber] - numberAddressesInPreviousBracket)) / 10000; // Update numberAddressesInPreviousBracket numberAddressesInPreviousBracket = _numberTicketsPerLotteryId[_lotteryId][transformedWinningNumber]; } // A. No CAKE to distribute, they are added to the amount to withdraw to treasury address } else { _lotteries[_lotteryId].cakePerBracket[j] = 0; amountToWithdrawToTreasury += (_lotteries[_lotteryId].rewardsBreakdown[j] * amountToShareToWinners) / 10000; } } // Update internal statuses for lottery _lotteries[_lotteryId].finalNumber = finalNumber; _lotteries[_lotteryId].status = Status.Claimable; if (_autoInjection) { pendingInjectionNextLottery = amountToWithdrawToTreasury; amountToWithdrawToTreasury = 0; } amountToWithdrawToTreasury += (_lotteries[_lotteryId].amountCollectedInCake - amountToShareToWinners); // Transfer CAKE to treasury address cakeToken.safeTransfer(treasuryAddress, amountToWithdrawToTreasury); emit LotteryNumberDrawn(currentLotteryId, finalNumber, numberAddressesInPreviousBracket); } /** * @notice Change the random generator * @dev The calls to functions are used to verify the new generator implements them properly. * It is necessary to wait for the VRF response before starting a round. * Callable only by the contract owner * @param _randomGeneratorAddress: address of the random generator */ function changeRandomGenerator(address _randomGeneratorAddress) external onlyOwner { require( (currentLotteryId == 0) || (_lotteries[currentLotteryId].status == Status.Claimable), "Lottery not in claimable" ); // Request a random number from the generator based on a seed IRandomNumberGenerator(_randomGeneratorAddress).getRandomNumber( uint256(keccak256(abi.encodePacked(currentLotteryId, currentTicketId))) ); // Calculate the finalNumber based on the randomResult generated by ChainLink's fallback IRandomNumberGenerator(_randomGeneratorAddress).viewRandomResult(); randomGenerator = IRandomNumberGenerator(_randomGeneratorAddress); emit NewRandomGenerator(_randomGeneratorAddress); } /** * @notice Inject funds * @param _lotteryId: lottery id * @param _amount: amount to inject in CAKE token * @dev Callable by owner or injector address */ function injectFunds(uint256 _lotteryId, uint256 _amount) external override onlyOwnerOrInjector { require(_lotteries[_lotteryId].status == Status.Open, "Lottery not open"); cakeToken.safeTransferFrom(address(msg.sender), address(this), _amount); _lotteries[_lotteryId].amountCollectedInCake += _amount; emit LotteryInjection(_lotteryId, _amount); } /** * @notice Start the lottery * @dev Callable by operator * @param _endTime: endTime of the lottery * @param _priceTicketInCake: price of a ticket in CAKE * @param _discountDivisor: the divisor to calculate the discount magnitude for bulks * @param _rewardsBreakdown: breakdown of rewards per bracket (must sum to 10,000) * @param _treasuryFee: treasury fee (10,000 = 100%, 100 = 1%) */ function startLottery( uint256 _endTime, uint256 _priceTicketInCake, uint256 _discountDivisor, uint256[6] calldata _rewardsBreakdown, uint256 _treasuryFee ) external override onlyOperator { require( (currentLotteryId == 0) || (_lotteries[currentLotteryId].status == Status.Claimable), "Not time to start lottery" ); require( ((_endTime - block.timestamp) > MIN_LENGTH_LOTTERY) && ((_endTime - block.timestamp) < MAX_LENGTH_LOTTERY), "Lottery length outside of range" ); require( (_priceTicketInCake >= minPriceTicketInCake) && (_priceTicketInCake <= maxPriceTicketInCake), "Outside of limits" ); require(_discountDivisor >= MIN_DISCOUNT_DIVISOR, "Discount divisor too low"); require(_treasuryFee <= MAX_TREASURY_FEE, "Treasury fee too high"); require( (_rewardsBreakdown[0] + _rewardsBreakdown[1] + _rewardsBreakdown[2] + _rewardsBreakdown[3] + _rewardsBreakdown[4] + _rewardsBreakdown[5]) == 10000, "Rewards must equal 10000" ); currentLotteryId++; _lotteries[currentLotteryId] = Lottery({ status: Status.Open, startTime: block.timestamp, endTime: _endTime, priceTicketInCake: _priceTicketInCake, discountDivisor: _discountDivisor, rewardsBreakdown: _rewardsBreakdown, treasuryFee: _treasuryFee, cakePerBracket: [uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0)], countWinnersPerBracket: [uint256(0), uint256(0), uint256(0), uint256(0), uint256(0), uint256(0)], firstTicketId: currentTicketId, firstTicketIdNextLottery: currentTicketId, amountCollectedInCake: pendingInjectionNextLottery, finalNumber: 0 }); emit LotteryOpen( currentLotteryId, block.timestamp, _endTime, _priceTicketInCake, currentTicketId, pendingInjectionNextLottery ); pendingInjectionNextLottery = 0; } /** * @notice It allows the admin to recover wrong tokens sent to the contract * @param _tokenAddress: the address of the token to withdraw * @param _tokenAmount: the number of token amount to withdraw * @dev Only callable by owner. */ function recoverWrongTokens(address _tokenAddress, uint256 _tokenAmount) external onlyOwner { require(_tokenAddress != address(cakeToken), "Cannot be CAKE token"); IERC20(_tokenAddress).safeTransfer(address(msg.sender), _tokenAmount); emit AdminTokenRecovery(_tokenAddress, _tokenAmount); } /** * @notice Set CAKE price ticket upper/lower limit * @dev Only callable by owner * @param _minPriceTicketInCake: minimum price of a ticket in CAKE * @param _maxPriceTicketInCake: maximum price of a ticket in CAKE */ function setMinAndMaxTicketPriceInCake(uint256 _minPriceTicketInCake, uint256 _maxPriceTicketInCake) external onlyOwner { require(_minPriceTicketInCake <= _maxPriceTicketInCake, "minPrice must be < maxPrice"); minPriceTicketInCake = _minPriceTicketInCake; maxPriceTicketInCake = _maxPriceTicketInCake; } /** * @notice Set max number of tickets * @dev Only callable by owner */ function setMaxNumberTicketsPerBuy(uint256 _maxNumberTicketsPerBuy) external onlyOwner { require(_maxNumberTicketsPerBuy != 0, "Must be > 0"); maxNumberTicketsPerBuyOrClaim = _maxNumberTicketsPerBuy; } /** * @notice Set operator, treasury, and injector addresses * @dev Only callable by owner * @param _operatorAddress: address of the operator * @param _treasuryAddress: address of the treasury * @param _injectorAddress: address of the injector */ function setOperatorAndTreasuryAndInjectorAddresses( address _operatorAddress, address _treasuryAddress, address _injectorAddress ) external onlyOwner { require(_operatorAddress != address(0), "Cannot be zero address"); require(_treasuryAddress != address(0), "Cannot be zero address"); require(_injectorAddress != address(0), "Cannot be zero address"); operatorAddress = _operatorAddress; treasuryAddress = _treasuryAddress; injectorAddress = _injectorAddress; emit NewOperatorAndTreasuryAndInjectorAddresses(_operatorAddress, _treasuryAddress, _injectorAddress); } /** * @notice Calculate price of a set of tickets * @param _discountDivisor: divisor for the discount * @param _priceTicket price of a ticket (in CAKE) * @param _numberTickets number of tickets to buy */ function calculateTotalPriceForBulkTickets( uint256 _discountDivisor, uint256 _priceTicket, uint256 _numberTickets ) external pure returns (uint256) { require(_discountDivisor >= MIN_DISCOUNT_DIVISOR, "Must be >= MIN_DISCOUNT_DIVISOR"); require(_numberTickets != 0, "Number of tickets must be > 0"); return _calculateTotalPriceForBulkTickets(_discountDivisor, _priceTicket, _numberTickets); } /** * @notice View current lottery id */ function viewCurrentLotteryId() external view override returns (uint256) { return currentLotteryId; } /** * @notice View lottery information * @param _lotteryId: lottery id */ function viewLottery(uint256 _lotteryId) external view returns (Lottery memory) { return _lotteries[_lotteryId]; } /** * @notice View ticker statuses and numbers for an array of ticket ids * @param _ticketIds: array of _ticketId */ function viewNumbersAndStatusesForTicketIds(uint256[] calldata _ticketIds) external view returns (uint32[] memory, bool[] memory) { uint256 length = _ticketIds.length; uint32[] memory ticketNumbers = new uint32[](length); bool[] memory ticketStatuses = new bool[](length); for (uint256 i = 0; i < length; i++) { ticketNumbers[i] = _tickets[_ticketIds[i]].number; if (_tickets[_ticketIds[i]].owner == address(0)) { ticketStatuses[i] = true; } else { ticketStatuses[i] = false; } } return (ticketNumbers, ticketStatuses); } /** * @notice View rewards for a given ticket, providing a bracket, and lottery id * @dev Computations are mostly offchain. This is used to verify a ticket! * @param _lotteryId: lottery id * @param _ticketId: ticket id * @param _bracket: bracket for the ticketId to verify the claim and calculate rewards */ function viewRewardsForTicketId( uint256 _lotteryId, uint256 _ticketId, uint32 _bracket ) external view returns (uint256) { // Check lottery is in claimable status if (_lotteries[_lotteryId].status != Status.Claimable) { return 0; } // Check ticketId is within range if ( (_lotteries[_lotteryId].firstTicketIdNextLottery < _ticketId) && (_lotteries[_lotteryId].firstTicketId >= _ticketId) ) { return 0; } return _calculateRewardsForTicketId(_lotteryId, _ticketId, _bracket); } /** * @notice View user ticket ids, numbers, and statuses of user for a given lottery * @param _user: user address * @param _lotteryId: lottery id * @param _cursor: cursor to start where to retrieve the tickets * @param _size: the number of tickets to retrieve */ function viewUserInfoForLotteryId( address _user, uint256 _lotteryId, uint256 _cursor, uint256 _size ) external view override returns ( uint256[] memory, uint32[] memory, bool[] memory, uint256 ) { uint256 length = _size; uint256 numberTicketsBoughtAtLotteryId = _userTicketIdsPerLotteryId[_user][_lotteryId].length; if (length > (numberTicketsBoughtAtLotteryId - _cursor)) { length = numberTicketsBoughtAtLotteryId - _cursor; } uint256[] memory lotteryTicketIds = new uint256[](length); uint32[] memory ticketNumbers = new uint32[](length); bool[] memory ticketStatuses = new bool[](length); for (uint256 i = 0; i < length; i++) { lotteryTicketIds[i] = _userTicketIdsPerLotteryId[_user][_lotteryId][i + _cursor]; ticketNumbers[i] = _tickets[lotteryTicketIds[i]].number; // True = ticket claimed if (_tickets[lotteryTicketIds[i]].owner == address(0)) { ticketStatuses[i] = true; } else { // ticket not claimed (includes the ones that cannot be claimed) ticketStatuses[i] = false; } } return (lotteryTicketIds, ticketNumbers, ticketStatuses, _cursor + length); } /** * @notice Calculate rewards for a given ticket * @param _lotteryId: lottery id * @param _ticketId: ticket id * @param _bracket: bracket for the ticketId to verify the claim and calculate rewards */ function _calculateRewardsForTicketId( uint256 _lotteryId, uint256 _ticketId, uint32 _bracket ) internal view returns (uint256) { // Retrieve the winning number combination uint32 winningTicketNumber = _lotteries[_lotteryId].finalNumber; // Retrieve the user number combination from the ticketId uint32 userNumber = _tickets[_ticketId].number; // Apply transformation to verify the claim provided by the user is true uint32 transformedWinningNumber = _bracketCalculator[_bracket] + (winningTicketNumber % (uint32(10)**(_bracket + 1))); uint32 transformedUserNumber = _bracketCalculator[_bracket] + (userNumber % (uint32(10)**(_bracket + 1))); // Confirm that the two transformed numbers are the same, if not throw if (transformedWinningNumber == transformedUserNumber) { return _lotteries[_lotteryId].cakePerBracket[_bracket]; } else { return 0; } } /** * @notice Calculate final price for bulk of tickets * @param _discountDivisor: divisor for the discount (the smaller it is, the greater the discount is) * @param _priceTicket: price of a ticket * @param _numberTickets: number of tickets purchased */ function _calculateTotalPriceForBulkTickets( uint256 _discountDivisor, uint256 _priceTicket, uint256 _numberTickets ) internal pure returns (uint256) { return (_priceTicket * _numberTickets * (_discountDivisor + 1 - _numberTickets)) / _discountDivisor; } /** * @notice Check if an address is a contract */ function _isContract(address _addr) internal view returns (bool) { uint256 size; assembly { size := extcodesize(_addr) } return size > 0; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (access/Ownable.sol) pragma solidity ^0.8.0; import "../utils/Context.sol"; /** * @dev Contract module which provides a basic access control mechanism, where * there is an account (an owner) that can be granted exclusive access to * specific functions. * * By default, the owner account will be the one that deploys the contract. This * can later be changed with {transferOwnership}. * * This module is used through inheritance. It will make available the modifier * `onlyOwner`, which can be applied to your functions to restrict their use to * the owner. */ abstract contract Ownable is Context { address private _owner; event OwnershipTransferred(address indexed previousOwner, address indexed newOwner); /** * @dev Initializes the contract setting the deployer as the initial owner. */ constructor() { _transferOwnership(_msgSender()); } /** * @dev Returns the address of the current owner. */ function owner() public view virtual returns (address) { return _owner; } /** * @dev Throws if called by any account other than the owner. */ modifier onlyOwner() { require(owner() == _msgSender(), "Ownable: caller is not the owner"); _; } /** * @dev Leaves the contract without owner. It will not be possible to call * `onlyOwner` functions anymore. Can only be called by the current owner. * * NOTE: Renouncing ownership will leave the contract without an owner, * thereby removing any functionality that is only available to the owner. */ function renounceOwnership() public virtual onlyOwner { _transferOwnership(address(0)); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Can only be called by the current owner. */ function transferOwnership(address newOwner) public virtual onlyOwner { require(newOwner != address(0), "Ownable: new owner is the zero address"); _transferOwnership(newOwner); } /** * @dev Transfers ownership of the contract to a new account (`newOwner`). * Internal function without access restriction. */ function _transferOwnership(address newOwner) internal virtual { address oldOwner = _owner; _owner = newOwner; emit OwnershipTransferred(oldOwner, newOwner); } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol) pragma solidity ^0.8.0; /** * @dev Contract module that helps prevent reentrant calls to a function. * * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier * available, which can be applied to functions to make sure there are no nested * (reentrant) calls to them. * * Note that because there is a single `nonReentrant` guard, functions marked as * `nonReentrant` may not call one another. This can be worked around by making * those functions `private`, and then adding `external` `nonReentrant` entry * points to them. * * TIP: If you would like to learn more about reentrancy and alternative ways * to protect against it, check out our blog post * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul]. */ abstract contract ReentrancyGuard { // Booleans are more expensive than uint256 or any type that takes up a full // word because each write operation emits an extra SLOAD to first read the // slot's contents, replace the bits taken up by the boolean, and then write // back. This is the compiler's defense against contract upgrades and // pointer aliasing, and it cannot be disabled. // The values being non-zero value makes deployment a bit more expensive, // but in exchange the refund on every call to nonReentrant will be lower in // amount. Since refunds are capped to a percentage of the total // transaction's gas, it is best to keep them low in cases like this one, to // increase the likelihood of the full refund coming into effect. uint256 private constant _NOT_ENTERED = 1; uint256 private constant _ENTERED = 2; uint256 private _status; constructor() { _status = _NOT_ENTERED; } /** * @dev Prevents a contract from calling itself, directly or indirectly. * Calling a `nonReentrant` function from another `nonReentrant` * function is not supported. It is possible to prevent this from happening * by making the `nonReentrant` function external, and making it call a * `private` function that does the actual work. */ modifier nonReentrant() { // On the first call to nonReentrant, _notEntered will be true require(_status != _ENTERED, "ReentrancyGuard: reentrant call"); // Any calls to nonReentrant after this point will fail _status = _ENTERED; _; // By storing the original value once again, a refund is triggered (see // https://eips.ethereum.org/EIPS/eip-2200) _status = _NOT_ENTERED; } }
// SPDX-License-Identifier: MIT // OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol) pragma solidity ^0.8.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 `to`. * * Returns a boolean value indicating whether the operation succeeded. * * Emits a {Transfer} event. */ function transfer(address to, 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); /** * @dev Moves `amount` tokens from `from` to `to` 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 from, address to, 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 // OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol) pragma solidity ^0.8.0; import "../IERC20.sol"; import "../../../utils/Address.sol"; /** * @title SafeERC20 * @dev Wrappers around ERC20 operations that throw on failure (when the token * contract returns false). Tokens that return no value (and instead revert or * throw on failure) are also supported, non-reverting calls are assumed to be * successful. * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract, * which allows you to call the safe operations as `token.safeTransfer(...)`, etc. */ library SafeERC20 { using Address for address; function safeTransfer( IERC20 token, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value)); } function safeTransferFrom( IERC20 token, address from, address to, uint256 value ) internal { _callOptionalReturn(token, abi.encodeWithSelector(token.transferFrom.selector, from, to, value)); } /** * @dev Deprecated. This function has issues similar to the ones found in * {IERC20-approve}, and its usage is discouraged. * * Whenever possible, use {safeIncreaseAllowance} and * {safeDecreaseAllowance} instead. */ function safeApprove( IERC20 token, address spender, uint256 value ) internal { // safeApprove should only be called when setting an initial allowance, // or when resetting it to zero. To increase and decrease it, use // 'safeIncreaseAllowance' and 'safeDecreaseAllowance' require( (value == 0) || (token.allowance(address(this), spender) == 0), "SafeERC20: approve from non-zero to non-zero allowance" ); _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, value)); } function safeIncreaseAllowance( IERC20 token, address spender, uint256 value ) internal { uint256 newAllowance = token.allowance(address(this), spender) + value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } function safeDecreaseAllowance( IERC20 token, address spender, uint256 value ) internal { unchecked { uint256 oldAllowance = token.allowance(address(this), spender); require(oldAllowance >= value, "SafeERC20: decreased allowance below zero"); uint256 newAllowance = oldAllowance - value; _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance)); } } /** * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement * on the return value: the return value is optional (but if data is returned, it must not be false). * @param token The token targeted by the call. * @param data The call data (encoded using abi.encode or one of its variants). */ function _callOptionalReturn(IERC20 token, bytes memory data) private { // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that // the target address contains contract code and also asserts for success in the low-level call. bytes memory returndata = address(token).functionCall(data, "SafeERC20: low-level call failed"); if (returndata.length > 0) { // Return data is optional require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed"); } } }
// SPDX-License-Identifier: MIT pragma solidity ^0.8.4; interface IRandomNumberGenerator { /** * Requests randomness from a user-provided seed */ function getRandomNumber(uint256 _seed) external; /** * View latest lotteryId numbers */ function viewLatestLotteryId() external view returns (uint256); /** * Views random result */ function viewRandomResult() external view returns (uint32); }
// SPDX-License-Identifier: MIT pragma solidity >=0.6.0; interface IPancakeSwapLottery { /** * @notice Buy tickets for the current lottery * @param _lotteryId: lotteryId * @param _ticketNumbers: array of ticket numbers between 1,000,000 and 1,999,999 * @dev Callable by users */ function buyTickets(uint256 _lotteryId, uint32[] calldata _ticketNumbers) external; /** * @notice Claim a set of winning tickets for a lottery * @param _lotteryId: lottery id * @param _ticketIds: array of ticket ids * @param _brackets: array of brackets for the ticket ids * @dev Callable by users only, not contract! */ function claimTickets( uint256 _lotteryId, uint256[] calldata _ticketIds, uint32[] calldata _brackets ) external; /** * @notice Close lottery * @param _lotteryId: lottery id * @dev Callable by operator */ function closeLottery(uint256 _lotteryId) external; /** * @notice Draw the final number, calculate reward in CAKE per group, and make lottery claimable * @param _lotteryId: lottery id * @param _autoInjection: reinjects funds into next lottery (vs. withdrawing all) * @dev Callable by operator */ function drawFinalNumberAndMakeLotteryClaimable(uint256 _lotteryId, bool _autoInjection) external; /** * @notice Inject funds * @param _lotteryId: lottery id * @param _amount: amount to inject in CAKE token * @dev Callable by operator */ function injectFunds(uint256 _lotteryId, uint256 _amount) external; /** * @notice Start the lottery * @dev Callable by operator * @param _endTime: endTime of the lottery * @param _priceTicketInCake: price of a ticket in CAKE * @param _discountDivisor: the divisor to calculate the discount magnitude for bulks * @param _rewardsBreakdown: breakdown of rewards per bracket (must sum to 10,000) * @param _treasuryFee: treasury fee (10,000 = 100%, 100 = 1%) */ function startLottery( uint256 _endTime, uint256 _priceTicketInCake, uint256 _discountDivisor, uint256[6] calldata _rewardsBreakdown, uint256 _treasuryFee ) external; /** * @notice View current lottery id */ function viewCurrentLotteryId() external returns (uint256); /** * @notice View user ticket ids, numbers, and statuses of user for a given lottery * @param _user: user address * @param _lotteryId: lottery id * @param _cursor: cursor to start where to retrieve the tickets * @param _size: the number of tickets to retrieve */ function viewUserInfoForLotteryId( address _user, uint256 _lotteryId, uint256 _cursor, uint256 _size ) external view returns ( uint256[] memory, uint32[] memory, bool[] memory, uint256 ); }
// 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 (last updated v4.5.0) (utils/Address.sol) pragma solidity ^0.8.1; /** * @dev Collection of functions related to the address type */ library Address { /** * @dev Returns true if `account` is a contract. * * [IMPORTANT] * ==== * It is unsafe to assume that an address for which this function returns * false is an externally-owned account (EOA) and not a contract. * * Among others, `isContract` will return false for the following * types of addresses: * * - an externally-owned account * - a contract in construction * - an address where a contract will be created * - an address where a contract lived, but was destroyed * ==== * * [IMPORTANT] * ==== * You shouldn't rely on `isContract` to protect against flash loan attacks! * * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract * constructor. * ==== */ function isContract(address account) internal view returns (bool) { // This method relies on extcodesize/address.code.length, which returns 0 // for contracts in construction, since the code is only stored at the end // of the constructor execution. return account.code.length > 0; } /** * @dev Replacement for Solidity's `transfer`: sends `amount` wei to * `recipient`, forwarding all available gas and reverting on errors. * * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost * of certain opcodes, possibly making contracts go over the 2300 gas limit * imposed by `transfer`, making them unable to receive funds via * `transfer`. {sendValue} removes this limitation. * * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more]. * * IMPORTANT: because control is transferred to `recipient`, care must be * taken to not create reentrancy vulnerabilities. Consider using * {ReentrancyGuard} or the * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern]. */ function sendValue(address payable recipient, uint256 amount) internal { require(address(this).balance >= amount, "Address: insufficient balance"); (bool success, ) = recipient.call{value: amount}(""); require(success, "Address: unable to send value, recipient may have reverted"); } /** * @dev Performs a Solidity function call using a low level `call`. A * plain `call` is an unsafe replacement for a function call: use this * function instead. * * If `target` reverts with a revert reason, it is bubbled up by this * function (like regular Solidity function calls). * * Returns the raw returned data. To convert to the expected return value, * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`]. * * Requirements: * * - `target` must be a contract. * - calling `target` with `data` must not revert. * * _Available since v3.1._ */ function functionCall(address target, bytes memory data) internal returns (bytes memory) { return functionCall(target, data, "Address: low-level call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with * `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { return functionCallWithValue(target, data, 0, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but also transferring `value` wei to `target`. * * Requirements: * * - the calling contract must have an ETH balance of at least `value`. * - the called Solidity function must be `payable`. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value ) internal returns (bytes memory) { return functionCallWithValue(target, data, value, "Address: low-level call with value failed"); } /** * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but * with `errorMessage` as a fallback revert reason when `target` reverts. * * _Available since v3.1._ */ function functionCallWithValue( address target, bytes memory data, uint256 value, string memory errorMessage ) internal returns (bytes memory) { require(address(this).balance >= value, "Address: insufficient balance for call"); require(isContract(target), "Address: call to non-contract"); (bool success, bytes memory returndata) = target.call{value: value}(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) { return functionStaticCall(target, data, "Address: low-level static call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a static call. * * _Available since v3.3._ */ function functionStaticCall( address target, bytes memory data, string memory errorMessage ) internal view returns (bytes memory) { require(isContract(target), "Address: static call to non-contract"); (bool success, bytes memory returndata) = target.staticcall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) { return functionDelegateCall(target, data, "Address: low-level delegate call failed"); } /** * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`], * but performing a delegate call. * * _Available since v3.4._ */ function functionDelegateCall( address target, bytes memory data, string memory errorMessage ) internal returns (bytes memory) { require(isContract(target), "Address: delegate call to non-contract"); (bool success, bytes memory returndata) = target.delegatecall(data); return verifyCallResult(success, returndata, errorMessage); } /** * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the * revert reason using the provided one. * * _Available since v4.3._ */ function verifyCallResult( bool success, bytes memory returndata, string memory errorMessage ) internal pure returns (bytes memory) { if (success) { return returndata; } else { // Look for revert reason and bubble it up if present if (returndata.length > 0) { // The easiest way to bubble the revert reason is using memory via assembly assembly { let returndata_size := mload(returndata) revert(add(32, returndata), returndata_size) } } else { revert(errorMessage); } } } }
{ "optimizer": { "enabled": true, "runs": 200 }, "outputSelection": { "*": { "*": [ "evm.bytecode", "evm.deployedBytecode", "devdoc", "userdoc", "metadata", "abi" ] } }, "libraries": {} }
[{"inputs":[{"internalType":"address","name":"_cakeTokenAddress","type":"address"},{"internalType":"address","name":"_randomGeneratorAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"token","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"AdminTokenRecovery","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lotteryId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"firstTicketIdNextLottery","type":"uint256"}],"name":"LotteryClose","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lotteryId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"injectedAmount","type":"uint256"}],"name":"LotteryInjection","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lotteryId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"finalNumber","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"countWinningTickets","type":"uint256"}],"name":"LotteryNumberDrawn","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"lotteryId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"startTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"endTime","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"priceTicketInCake","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"firstTicketId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"injectedAmount","type":"uint256"}],"name":"LotteryOpen","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"address","name":"treasury","type":"address"},{"indexed":false,"internalType":"address","name":"injector","type":"address"}],"name":"NewOperatorAndTreasuryAndInjectorAddresses","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"randomGenerator","type":"address"}],"name":"NewRandomGenerator","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"claimer","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"},{"indexed":true,"internalType":"uint256","name":"lotteryId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numberTickets","type":"uint256"}],"name":"TicketsClaim","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"buyer","type":"address"},{"indexed":true,"internalType":"uint256","name":"lotteryId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"numberTickets","type":"uint256"}],"name":"TicketsPurchase","type":"event"},{"inputs":[],"name":"MAX_LENGTH_LOTTERY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TREASURY_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_DISCOUNT_DIVISOR","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MIN_LENGTH_LOTTERY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lotteryId","type":"uint256"},{"internalType":"uint32[]","name":"_ticketNumbers","type":"uint32[]"}],"name":"buyTickets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cakeToken","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_discountDivisor","type":"uint256"},{"internalType":"uint256","name":"_priceTicket","type":"uint256"},{"internalType":"uint256","name":"_numberTickets","type":"uint256"}],"name":"calculateTotalPriceForBulkTickets","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"_randomGeneratorAddress","type":"address"}],"name":"changeRandomGenerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lotteryId","type":"uint256"},{"internalType":"uint256[]","name":"_ticketIds","type":"uint256[]"},{"internalType":"uint32[]","name":"_brackets","type":"uint32[]"}],"name":"claimTickets","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lotteryId","type":"uint256"}],"name":"closeLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentLotteryId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"currentTicketId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lotteryId","type":"uint256"},{"internalType":"bool","name":"_autoInjection","type":"bool"}],"name":"drawFinalNumberAndMakeLotteryClaimable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lotteryId","type":"uint256"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"injectFunds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"injectorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNumberTicketsPerBuyOrClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxPriceTicketInCake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minPriceTicketInCake","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"operatorAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pendingInjectionNextLottery","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"randomGenerator","outputs":[{"internalType":"contract IRandomNumberGenerator","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_tokenAddress","type":"address"},{"internalType":"uint256","name":"_tokenAmount","type":"uint256"}],"name":"recoverWrongTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxNumberTicketsPerBuy","type":"uint256"}],"name":"setMaxNumberTicketsPerBuy","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minPriceTicketInCake","type":"uint256"},{"internalType":"uint256","name":"_maxPriceTicketInCake","type":"uint256"}],"name":"setMinAndMaxTicketPriceInCake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_operatorAddress","type":"address"},{"internalType":"address","name":"_treasuryAddress","type":"address"},{"internalType":"address","name":"_injectorAddress","type":"address"}],"name":"setOperatorAndTreasuryAndInjectorAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_endTime","type":"uint256"},{"internalType":"uint256","name":"_priceTicketInCake","type":"uint256"},{"internalType":"uint256","name":"_discountDivisor","type":"uint256"},{"internalType":"uint256[6]","name":"_rewardsBreakdown","type":"uint256[6]"},{"internalType":"uint256","name":"_treasuryFee","type":"uint256"}],"name":"startLottery","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasuryAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"viewCurrentLotteryId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lotteryId","type":"uint256"}],"name":"viewLottery","outputs":[{"components":[{"internalType":"enum PancakeSwapLottery.Status","name":"status","type":"uint8"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"},{"internalType":"uint256","name":"priceTicketInCake","type":"uint256"},{"internalType":"uint256","name":"discountDivisor","type":"uint256"},{"internalType":"uint256[6]","name":"rewardsBreakdown","type":"uint256[6]"},{"internalType":"uint256","name":"treasuryFee","type":"uint256"},{"internalType":"uint256[6]","name":"cakePerBracket","type":"uint256[6]"},{"internalType":"uint256[6]","name":"countWinnersPerBracket","type":"uint256[6]"},{"internalType":"uint256","name":"firstTicketId","type":"uint256"},{"internalType":"uint256","name":"firstTicketIdNextLottery","type":"uint256"},{"internalType":"uint256","name":"amountCollectedInCake","type":"uint256"},{"internalType":"uint32","name":"finalNumber","type":"uint32"}],"internalType":"struct PancakeSwapLottery.Lottery","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"_ticketIds","type":"uint256[]"}],"name":"viewNumbersAndStatusesForTicketIds","outputs":[{"internalType":"uint32[]","name":"","type":"uint32[]"},{"internalType":"bool[]","name":"","type":"bool[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_lotteryId","type":"uint256"},{"internalType":"uint256","name":"_ticketId","type":"uint256"},{"internalType":"uint32","name":"_bracket","type":"uint32"}],"name":"viewRewardsForTicketId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_user","type":"address"},{"internalType":"uint256","name":"_lotteryId","type":"uint256"},{"internalType":"uint256","name":"_cursor","type":"uint256"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"viewUserInfoForLotteryId","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint32[]","name":"","type":"uint32[]"},{"internalType":"bool[]","name":"","type":"bool[]"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]
Contract Creation Code
608060405260646007556802b5e3af16b18800006008556611c37937e080006009553480156200002e57600080fd5b5060405162003de338038062003de3833981016040819052620000519162000219565b60016000556200006133620001aa565b600b80546001600160a01b039384166001600160a01b0319918216178255600c805493909416921691909117909155600f6020527ff4803e074bd026baaf6ed2e288c9515f68c72fb7216eebdd7cae1718a53ec375805463ffffffff199081166001179091557f169f97de0d9a84d840042b17d3c6b9638b3d6fd9024c9eb0c7a306a17b49f88f805482169092179091557fa74ba3945261e09fde15ba3db55005b205e61eeb4ad811ac0faa2b315bffeead80548216606f1790557f45f76dafbbad695564362934e24d72eedc57f9fc1a65f39bca62176cc8296828805482166104571790557f367ccd2d0ac16bf7110a5dffe0801fdc9452a95a1adb7e1a12fe97dd3e9a4edd80548216612b6717905560056000527f6bda57492eba051cb4a12a1e19df47c9755d78165341d4009b1d09b3f361620480549091166201b20717905562000250565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80516001600160a01b03811681146200021457600080fd5b919050565b600080604083850312156200022c578182fd5b6200023783620001fc565b91506200024760208401620001fc565b90509250929050565b613b8380620002606000396000f3fe608060405234801561001057600080fd5b50600436106102115760003560e01c806388303dbd11610125578063c4937ab9116100ad578063da7429f81161007c578063da7429f81461043b578063db19da0d1461044e578063dcbad90d14610458578063f2b3c8091461046b578063f2fde38b1461047457600080fd5b8063c4937ab9146103ef578063c5f956af14610402578063c914914f14610415578063da4ca0391461042857600080fd5b806398359fa1116100f457806398359fa1146103905780639c384653146103a35780639d8ca531146103b6578063b1829b82146103c9578063c38de539146103dc57600080fd5b806388303dbd146103385780638904bf2f1461034b5780638da5cb5b1461035e5780638fc3539a1461036f57600080fd5b806331feb565116101a85780636b873788116101775780636b8737881461030c5780636be4097c1461031f578063715018a6146103285780637cb583bd1461024257806380a061601461033057600080fd5b806331feb565146102d25780633f138d4b146102db578063471aeab4146102f0578063686465b81461030357600080fd5b80631f73664b116101e45780631f73664b1461028d5780631fe86c6b146102965780632423807a1461029f5780632e530cae146102bf57600080fd5b806305531eeb1461021657806307fb5a9c14610242578063127effb21461025957806312a9769d14610284575b600080fd5b6102296102243660046132a9565b610487565b6040516102399493929190613638565b60405180910390f35b61024b61012c81565b604051908152602001610239565b60035461026c906001600160a01b031681565b6040516001600160a01b039091168152602001610239565b61024b600a5481565b61024b60085481565b61024b60075481565b6102b26102ad36600461333d565b6107ff565b60405161023991906137cf565b61024b6102cd3660046134f6565b61097c565b61024b60095481565b6102ee6102e9366004613280565b610a11565b005b6102ee6102fe36600461345d565b610af3565b61024b60065481565b6102ee61031a36600461333d565b610c44565b61024b60055481565b6102ee610cae565b60055461024b565b6102ee6103463660046133e4565b610ce4565b600b5461026c906001600160a01b031681565b6001546001600160a01b031661026c565b61038261037d3660046132e1565b6112c5565b6040516102399291906136ac565b6102ee61039e366004613224565b6114e1565b60025461026c906001600160a01b031681565b6102ee6103c436600461333d565b6116e8565b6102ee6103d73660046134a9565b6118fe565b6102ee6103ea36600461342e565b611e04565b61024b6103fd36600461347e565b6123fc565b60045461026c906001600160a01b031681565b6102ee61042336600461336d565b6124a8565b6102ee61043636600461323e565b612a65565b6102ee61044936600461345d565b612b85565b61024b6205472c81565b600c5461026c906001600160a01b031681565b61024b610bb881565b6102ee610482366004613224565b612c0a565b6001600160a01b0384166000908152601160209081526040808320868452909152812054606091829182919085906104bf8882613a37565b8211156104d3576104d08882613a37565b91505b60008267ffffffffffffffff8111156104fc57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610525578160200160208202803683370190505b50905060008367ffffffffffffffff81111561055157634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561057a578160200160208202803683370190505b50905060008467ffffffffffffffff8111156105a657634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156105cf578160200160208202803683370190505b50905060005b858110156107d957601160008f6001600160a01b03166001600160a01b0316815260200190815260200160002060008e81526020019081526020016000208c8261061f9190613892565b8154811061063d57634e487b7160e01b600052603260045260246000fd5b906000526020600020015484828151811061066857634e487b7160e01b600052603260045260246000fd5b602002602001018181525050600e600085838151811061069857634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060000160009054906101000a900463ffffffff168382815181106106e257634e487b7160e01b600052603260045260246000fd5b602002602001019063ffffffff16908163ffffffff168152505060006001600160a01b0316600e600086848151811061072b57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182528101919091526040016000205464010000000090046001600160a01b0316141561079457600182828151811061077f57634e487b7160e01b600052603260045260246000fd5b911515602092830291909101909101526107c7565b60008282815181106107b657634e487b7160e01b600052603260045260246000fd5b911515602092830291909101909101525b806107d181613a9f565b9150506105d5565b508282826107e7888f613892565b98509850985098505050505050945094509450949050565b6108076130d3565b6000828152600d60205260409081902081516101a081019092528054829060ff16600381111561084757634e487b7160e01b600052602160045260246000fd5b600381111561086657634e487b7160e01b600052602160045260246000fd5b81526001820154602082015260028201546040808301919091526003830154606083015260048301546080830152805160c081019182905260a09092019190600584019060069082845b8154815260200190600101908083116108b0575050509183525050600b82015460208201526040805160c081018252910190600c830160068282826020028201915b8154815260200190600101908083116108f25750505091835250506040805160c081019182905260209092019190601284019060069082845b81548152602001906001019080831161092b5750505091835250506018820154602082015260198201546040820152601a8201546060820152601b9091015463ffffffff1660809091015292915050565b600060036000858152600d602052604090205460ff1660038111156109b157634e487b7160e01b600052602160045260246000fd5b146109be57506000610a0a565b6000848152600d6020526040902060190154831180156109ef57506000848152600d60205260409020601801548311155b156109fc57506000610a0a565b610a07848484612ca5565b90505b9392505050565b6001546001600160a01b03163314610a445760405162461bcd60e51b8152600401610a3b9061373d565b60405180910390fd5b600b546001600160a01b0383811691161415610a995760405162461bcd60e51b815260206004820152601460248201527321b0b73737ba1031329021a0a5a2903a37b5b2b760611b6044820152606401610a3b565b610aad6001600160a01b0383163383612dbe565b604080516001600160a01b0384168152602081018390527f74545154aac348a3eac92596bd1971957ca94795f4e954ec5f613b55fab78129910160405180910390a15050565b6001546001600160a01b0316331480610b1657506002546001600160a01b031633145b610b5a5760405162461bcd60e51b81526020600482015260156024820152742737ba1037bbb732b91037b91034b73532b1ba37b960591b6044820152606401610a3b565b60016000838152600d602052604090205460ff166003811115610b8d57634e487b7160e01b600052602160045260246000fd5b14610bcd5760405162461bcd60e51b815260206004820152601060248201526f2637ba3a32b93c903737ba1037b832b760811b6044820152606401610a3b565b600b54610be5906001600160a01b0316333084612e26565b6000828152600d60205260408120601a018054839290610c06908490613892565b909155505060405181815282907f1bbd659dd628a25f7ff2eabb69c74a56939c539728282275c1c9c1a2d3e340499060200160405180910390a25050565b6001546001600160a01b03163314610c6e5760405162461bcd60e51b8152600401610a3b9061373d565b80610ca95760405162461bcd60e51b815260206004820152600b60248201526a04d757374206265203e20360ac1b6044820152606401610a3b565b600755565b6001546001600160a01b03163314610cd85760405162461bcd60e51b8152600401610a3b9061373d565b610ce26000612e64565b565b333b15610d2a5760405162461bcd60e51b815260206004820152601460248201527310dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b6044820152606401610a3b565b333214610d795760405162461bcd60e51b815260206004820152601a60248201527f50726f787920636f6e7472616374206e6f7420616c6c6f7765640000000000006044820152606401610a3b565b60026000541415610d9c5760405162461bcd60e51b8152600401610a3b90613772565b600260005580610de45760405162461bcd60e51b8152602060048201526013602482015272139bc81d1a58dad95d081cdc1958da599a5959606a1b6044820152606401610a3b565b600754811115610e295760405162461bcd60e51b815260206004820152601060248201526f546f6f206d616e79207469636b65747360801b6044820152606401610a3b565b60016000848152600d602052604090205460ff166003811115610e5c57634e487b7160e01b600052602160045260246000fd5b14610e9f5760405162461bcd60e51b81526020600482015260136024820152722637ba3a32b93c9034b9903737ba1037b832b760691b6044820152606401610a3b565b6000838152600d60205260409020600201544210610ef15760405162461bcd60e51b815260206004820152600f60248201526e2637ba3a32b93c9034b99037bb32b960891b6044820152606401610a3b565b6000838152600d602052604081206004810154600390910154610f15919084612eb6565b600b54909150610f30906001600160a01b0316333084612e26565b6000848152600d60205260408120601a018054839290610f51908490613892565b90915550600090505b82811015611282576000848483818110610f8457634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610f99919061352e565b9050620f42408163ffffffff1610158015610fbd5750621e847f8163ffffffff1611155b610ff95760405162461bcd60e51b815260206004820152600d60248201526c4f7574736964652072616e676560981b6044820152606401610a3b565b600086815260106020526040812090611013600a84613ade565b61101e9060016138aa565b63ffffffff1681526020810191909152604001600090812080549161104283613a9f565b9091555050600086815260106020526040812090611061606484613ade565b61106c90600b6138aa565b63ffffffff1681526020810191909152604001600090812080549161109083613a9f565b90915550506000868152601060205260408120906110b06103e884613ade565b6110bb90606f6138aa565b63ffffffff168152602081019190915260400160009081208054916110df83613a9f565b90915550506000868152601060205260408120906110ff61271084613ade565b61110b906104576138aa565b63ffffffff1681526020810191909152604001600090812080549161112f83613a9f565b9091555050600086815260106020526040812090611150620186a084613ade565b61115c90612b676138aa565b63ffffffff1681526020810191909152604001600090812080549161118083613a9f565b90915550506000868152601060205260408120906111a1620f424084613ade565b6111ae906201b2076138aa565b63ffffffff168152602081019190915260400160009081208054916111d283613a9f565b90915550503360008181526011602090815260408083208a84528252808320600680548254600181018455928652848620909201919091558151808301835263ffffffff808816825281850196875282548652600e9094529184209151825495516001600160a01b0316640100000000026001600160c01b0319909616931692909217939093179092558154919061126983613a9f565b919050555050808061127a90613a9f565b915050610f5a565b50604051828152849033907fd7d247b583de1023852eef87b48f54354dbec771d01bc2cc49e96094efc322b99060200160405180910390a3505060016000555050565b6060808260008167ffffffffffffffff8111156112f257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561131b578160200160208202803683370190505b50905060008267ffffffffffffffff81111561134757634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015611370578160200160208202803683370190505b50905060005b838110156114d257600e60008989848181106113a257634e487b7160e01b600052603260045260246000fd5b90506020020135815260200190815260200160002060000160009054906101000a900463ffffffff168382815181106113eb57634e487b7160e01b600052603260045260246000fd5b63ffffffff909216602092830291909101909101526000600e818a8a8581811061142557634e487b7160e01b600052603260045260246000fd5b602090810292909201358352508101919091526040016000205464010000000090046001600160a01b0316141561148d57600182828151811061147857634e487b7160e01b600052603260045260246000fd5b911515602092830291909101909101526114c0565b60008282815181106114af57634e487b7160e01b600052603260045260246000fd5b911515602092830291909101909101525b806114ca81613a9f565b915050611376565b509093509150505b9250929050565b6001546001600160a01b0316331461150b5760405162461bcd60e51b8152600401610a3b9061373d565b600554158061154d575060036005546000908152600d602052604090205460ff16600381111561154b57634e487b7160e01b600052602160045260246000fd5b145b6115995760405162461bcd60e51b815260206004820152601860248201527f4c6f7474657279206e6f7420696e20636c61696d61626c6500000000000000006044820152606401610a3b565b806001600160a01b031663b37217a46005546006546040516020016115c8929190918252602082015260400190565b60408051808303601f1901815290829052805160209091012060e083901b6001600160e01b03191682526004820152602401600060405180830381600087803b15801561161457600080fd5b505af1158015611628573d6000803e3d6000fd5b50505050806001600160a01b031663a1c4f55a6040518163ffffffff1660e01b815260040160206040518083038186803b15801561166557600080fd5b505afa158015611679573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061169d919061354a565b50600c80546001600160a01b0319166001600160a01b0383169081179091556040517f383f8cb39dfa7c3fb901a460dd449ea924868f0a92ff03da64740fffa5f1de6290600090a250565b6003546001600160a01b031633146117125760405162461bcd60e51b8152600401610a3b906137a9565b600260005414156117355760405162461bcd60e51b8152600401610a3b90613772565b600260005560016000828152600d602052604090205460ff16600381111561176d57634e487b7160e01b600052602160045260246000fd5b146117ad5760405162461bcd60e51b815260206004820152601060248201526f2637ba3a32b93c903737ba1037b832b760811b6044820152606401610a3b565b6000818152600d602052604090206002015442116118005760405162461bcd60e51b815260206004820152601060248201526f2637ba3a32b93c903737ba1037bb32b960811b6044820152606401610a3b565b6006546000828152600d6020908152604091829020601901839055600c548251918201859052918101929092526001600160a01b03169063b37217a49060600160408051808303601f1901815290829052805160209091012060e083901b6001600160e01b03191682526004820152602401600060405180830381600087803b15801561188c57600080fd5b505af11580156118a0573d6000803e3d6000fd5b5050506000828152600d6020908152604091829020805460ff1916600217905560065491519182528392507f3728e75294796694d59d2ffced9c394279baf7b9ebd2702db43f5f04bac67929910160405180910390a2506001600055565b6003546001600160a01b031633146119285760405162461bcd60e51b8152600401610a3b906137a9565b600554158061196a575060036005546000908152600d602052604090205460ff16600381111561196857634e487b7160e01b600052602160045260246000fd5b145b6119b65760405162461bcd60e51b815260206004820152601960248201527f4e6f742074696d6520746f207374617274206c6f7474657279000000000000006044820152606401610a3b565b61012c6119c34287613a37565b1180156119db57506205472c6119d94287613a37565b105b611a275760405162461bcd60e51b815260206004820152601f60248201527f4c6f7474657279206c656e677468206f757473696465206f662072616e6765006044820152606401610a3b565b6009548410158015611a3b57506008548411155b611a7b5760405162461bcd60e51b81526020600482015260116024820152704f757473696465206f66206c696d69747360781b6044820152606401610a3b565b61012c831015611acd5760405162461bcd60e51b815260206004820152601860248201527f446973636f756e742064697669736f7220746f6f206c6f7700000000000000006044820152606401610a3b565b610bb8811115611b175760405162461bcd60e51b81526020600482015260156024820152740a8e4cac2e6eae4f240cccaca40e8dede40d0d2ced605b1b6044820152606401610a3b565b60a0820135608083013560608401356040850135611b3a60208701358735613892565b611b449190613892565b611b4e9190613892565b611b589190613892565b611b629190613892565b61271014611bb25760405162461bcd60e51b815260206004820152601860248201527f52657761726473206d75737420657175616c20313030303000000000000000006044820152606401610a3b565b60058054906000611bc283613a9f565b9091555050604080516101a0810190915280600181526020014281526020018681526020018581526020018481526020018360068060200260405190810160405280929190826006602002808284376000920182905250928452505060208083018590526040805160c080820183528482528184018590528183018590526060808301869052608080840187905260a080850188905285890194909452845180840186528781528087018890528086018890528083018890528082018890528085018890529188019190915260065490870181905291860191909152600a549085015260e09093018290526005548252600d90522081518154829060ff19166001836003811115611ce357634e487b7160e01b600052602160045260246000fd5b02179055506020820151600182015560408201516002820155606082015160038201556080820151600482015560a0820151611d259060058301906006613154565b5060c0820151600b82015560e0820151611d4590600c8301906006613154565b50610100820151611d5c9060128301906006613154565b5061012082015160188201556101408201516019820155610160820151601a82015561018090910151601b909101805463ffffffff191663ffffffff909216919091179055600554600654600a5460408051428152602081018a9052908101889052606081019290925260808201527f367e70f8c0e0c0a6504d92172bda155c02022d532fc85b5d66a9c49e31c8bc779060a00160405180910390a250506000600a55505050565b6003546001600160a01b03163314611e2e5760405162461bcd60e51b8152600401610a3b906137a9565b60026000541415611e515760405162461bcd60e51b8152600401610a3b90613772565b60026000818155838152600d602052604090205460ff166003811115611e8757634e487b7160e01b600052602160045260246000fd5b14611ec85760405162461bcd60e51b81526020600482015260116024820152704c6f7474657279206e6f7420636c6f736560781b6044820152606401610a3b565b600c60009054906101000a90046001600160a01b03166001600160a01b031663fbe5d9176040518163ffffffff1660e01b815260040160206040518083038186803b158015611f1657600080fd5b505afa158015611f2a573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611f4e9190613355565b8214611f905760405162461bcd60e51b8152602060048201526011602482015270273ab6b132b939903737ba10323930bbb760791b6044820152606401610a3b565b600c54604080516350e27aad60e11b815290516000926001600160a01b03169163a1c4f55a916004808301926020929190829003018186803b158015611fd557600080fd5b505afa158015611fe9573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061200d919061354a565b6000848152600d60205260408120600b0154919250908190612710906120339082613a37565b6000878152600d60205260409020601a015461204f9190613a18565b61205991906138d2565b90506000805b60068163ffffffff16101561232757600061207b826005613a4e565b9050600061208a8260016138aa565b61209590600a61392d565b61209f9088613ade565b63ffffffff8084166000908152600f60205260409020546120c19291166138aa565b60008a815260106020908152604080832063ffffffff851684529091529020549091506120ef908790613a37565b60008a8152600d6020526040902060120163ffffffff84166006811061212557634e487b7160e01b600052603260045260246000fd5b0155600089815260106020908152604080832063ffffffff85168452909152902054612152908790613a37565b1561227b576000898152600d6020526040902060050163ffffffff83166006811061218d57634e487b7160e01b600052603260045260246000fd5b01541561227657600089815260106020908152604080832063ffffffff85168452909152902054612710906121c3908890613a37565b60008b8152600d60205260409020879060050163ffffffff8616600681106121fb57634e487b7160e01b600052603260045260246000fd5b01546122079190613a18565b61221191906138d2565b61221b91906138d2565b60008a8152600d60205260409020600c0163ffffffff84166006811061225157634e487b7160e01b600052603260045260246000fd5b0155600089815260106020908152604080832063ffffffff8516845290915290205495505b612312565b6000898152600d60205260408120600c0163ffffffff8416600681106122b157634e487b7160e01b600052603260045260246000fd5b01556000898152600d6020526040902061271090869060050163ffffffff8516600681106122ef57634e487b7160e01b600052603260045260246000fd5b01546122fb9190613a18565b61230591906138d2565b61230f9085613892565b93505b5050808061231f90613aba565b91505061205f565b506000868152600d60205260409020601b8101805463ffffffff871663ffffffff19909116179055805460ff19166003179055841561236657600a5560005b6000868152600d60205260409020601a0154612383908390613a37565b61238d9082613892565b600454600b549192506123ad916001600160a01b03908116911683612dbe565b6005546040805163ffffffff87168152602081018690527f98e31a6607b8b15b4d5b91de54f4c09ffe4c4cf162aa532c70b5213754e2e703910160405180910390a25050600160005550505050565b600061012c8410156124505760405162461bcd60e51b815260206004820152601f60248201527f4d757374206265203e3d204d494e5f444953434f554e545f44495649534f52006044820152606401610a3b565b8161249d5760405162461bcd60e51b815260206004820152601d60248201527f4e756d626572206f66207469636b657473206d757374206265203e20300000006044820152606401610a3b565b610a07848484612eb6565b333b156124ee5760405162461bcd60e51b815260206004820152601460248201527310dbdb9d1c9858dd081b9bdd08185b1b1bddd95960621b6044820152606401610a3b565b33321461253d5760405162461bcd60e51b815260206004820152601a60248201527f50726f787920636f6e7472616374206e6f7420616c6c6f7765640000000000006044820152606401610a3b565b600260005414156125605760405162461bcd60e51b8152600401610a3b90613772565b60026000558281146125a65760405162461bcd60e51b815260206004820152600f60248201526e09cdee840e6c2daca40d8cadccee8d608b1b6044820152606401610a3b565b826125e75760405162461bcd60e51b815260206004820152601160248201527004c656e677468206d757374206265203e3607c1b6044820152606401610a3b565b60075483111561262c5760405162461bcd60e51b815260206004820152601060248201526f546f6f206d616e79207469636b65747360801b6044820152606401610a3b565b60036000868152600d602052604090205460ff16600381111561265f57634e487b7160e01b600052602160045260246000fd5b146126a45760405162461bcd60e51b81526020600482015260156024820152744c6f7474657279206e6f7420636c61696d61626c6560581b6044820152606401610a3b565b6000805b84811015612a035760068484838181106126d257634e487b7160e01b600052603260045260246000fd5b90506020020160208101906126e7919061352e565b63ffffffff16106127315760405162461bcd60e51b8152602060048201526014602482015273427261636b6574206f7574206f662072616e676560601b6044820152606401610a3b565b600086868381811061275357634e487b7160e01b600052603260045260246000fd5b90506020020135905080600d60008a815260200190815260200160002060190154116127b55760405162461bcd60e51b81526020600482015260116024820152700a8d2c6d6cae892c840e8dede40d0d2ced607b1b6044820152606401610a3b565b6000888152600d60205260409020601801548110156128095760405162461bcd60e51b815260206004820152601060248201526f5469636b6574496420746f6f206c6f7760801b6044820152606401610a3b565b6000818152600e602052604090205464010000000090046001600160a01b031633146128675760405162461bcd60e51b815260206004820152600d60248201526c2737ba103a34329037bbb732b960991b6044820152606401610a3b565b6000818152600e602052604081208054640100000000600160c01b03191690556128c689838888878181106128ac57634e487b7160e01b600052603260045260246000fd5b90506020020160208101906128c1919061352e565b612ca5565b9050806129155760405162461bcd60e51b815260206004820152601960248201527f4e6f207072697a6520666f72207468697320627261636b6574000000000000006044820152606401610a3b565b85858481811061293557634e487b7160e01b600052603260045260246000fd5b905060200201602081019061294a919061352e565b63ffffffff166005146129e25761299c898388888781811061297c57634e487b7160e01b600052603260045260246000fd5b9050602002016020810190612991919061352e565b6128c19060016138aa565b156129e25760405162461bcd60e51b8152602060048201526016602482015275213930b1b5b2ba1036bab9ba103132903434b3b432b960511b6044820152606401610a3b565b6129ec8185613892565b9350505080806129fb90613a9f565b9150506126a8565b50600b54612a1b906001600160a01b03163383612dbe565b6040805182815260208101869052879133917f0f5fca62da8fb5d95525b49e5eaa7b20bc6bd9e2f6b64b493442d1c0bd6ef486910160405180910390a35050600160005550505050565b6001546001600160a01b03163314612a8f5760405162461bcd60e51b8152600401610a3b9061373d565b6001600160a01b038316612ab55760405162461bcd60e51b8152600401610a3b9061370d565b6001600160a01b038216612adb5760405162461bcd60e51b8152600401610a3b9061370d565b6001600160a01b038116612b015760405162461bcd60e51b8152600401610a3b9061370d565b600380546001600160a01b038581166001600160a01b0319928316811790935560048054868316908416811790915560028054928616929093168217909255604080519384526020840192909252908201527f3e945b7660001d46cfd5e729545f7f0b6c65bdee54066a91c7acad703f1b731e9060600160405180910390a1505050565b6001546001600160a01b03163314612baf5760405162461bcd60e51b8152600401610a3b9061373d565b80821115612bff5760405162461bcd60e51b815260206004820152601b60248201527f6d696e5072696365206d757374206265203c206d6178507269636500000000006044820152606401610a3b565b600991909155600855565b6001546001600160a01b03163314612c345760405162461bcd60e51b8152600401610a3b9061373d565b6001600160a01b038116612c995760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a3b565b612ca281612e64565b50565b6000838152600d60209081526040808320601b0154858452600e90925282205463ffffffff918216911682612cdb8560016138aa565b612ce690600a61392d565b612cf09084613ade565b63ffffffff8087166000908152600f6020526040902054612d129291166138aa565b90506000612d218660016138aa565b612d2c90600a61392d565b612d369084613ade565b63ffffffff8088166000908152600f6020526040902054612d589291166138aa565b90508063ffffffff168263ffffffff161415612db1576000888152600d60205260409020600c0163ffffffff871660068110612da457634e487b7160e01b600052603260045260246000fd5b0154945050505050610a0a565b6000945050505050610a0a565b6040516001600160a01b038316602482015260448101829052612e2190849063a9059cbb60e01b906064015b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152612eed565b505050565b6040516001600160a01b0380851660248301528316604482015260648101829052612e5e9085906323b872dd60e01b90608401612dea565b50505050565b600180546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60008382612ec5826001613892565b612ecf9190613a37565b612ed98486613a18565b612ee39190613a18565b610a0791906138d2565b6000612f42826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c6564815250856001600160a01b0316612fbf9092919063ffffffff16565b805190915015612e215780806020019051810190612f609190613321565b612e215760405162461bcd60e51b815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e6044820152691bdd081cdd58d8d9595960b21b6064820152608401610a3b565b6060610a078484600085856001600160a01b0385163b6130215760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a3b565b600080866001600160a01b0316858760405161303d919061361c565b60006040518083038185875af1925050503d806000811461307a576040519150601f19603f3d011682016040523d82523d6000602084013e61307f565b606091505b509150915061308f82828661309a565b979650505050505050565b606083156130a9575081610a0a565b8251156130b95782518084602001fd5b8160405162461bcd60e51b8152600401610a3b91906136da565b604080516101a0810190915280600081526020016000815260200160008152602001600081526020016000815260200161310b613192565b81526020016000815260200161311f613192565b815260200161312c613192565b8152602001600081526020016000815260200160008152602001600063ffffffff1681525090565b8260068101928215613182579160200282015b82811115613182578251825591602001919060010190613167565b5061318e9291506131b0565b5090565b6040518060c001604052806006906020820280368337509192915050565b5b8082111561318e57600081556001016131b1565b80356001600160a01b03811681146131dc57600080fd5b919050565b60008083601f8401126131f2578182fd5b50813567ffffffffffffffff811115613209578182fd5b6020830191508360208260051b85010111156114da57600080fd5b600060208284031215613235578081fd5b610a0a826131c5565b600080600060608486031215613252578182fd5b61325b846131c5565b9250613269602085016131c5565b9150613277604085016131c5565b90509250925092565b60008060408385031215613292578182fd5b61329b836131c5565b946020939093013593505050565b600080600080608085870312156132be578081fd5b6132c7856131c5565b966020860135965060408601359560600135945092505050565b600080602083850312156132f3578182fd5b823567ffffffffffffffff811115613309578283fd5b613315858286016131e1565b90969095509350505050565b600060208284031215613332578081fd5b8151610a0a81613b2d565b60006020828403121561334e578081fd5b5035919050565b600060208284031215613366578081fd5b5051919050565b600080600080600060608688031215613384578081fd5b85359450602086013567ffffffffffffffff808211156133a2578283fd5b6133ae89838a016131e1565b909650945060408801359150808211156133c6578283fd5b506133d3888289016131e1565b969995985093965092949392505050565b6000806000604084860312156133f8578283fd5b83359250602084013567ffffffffffffffff811115613415578283fd5b613421868287016131e1565b9497909650939450505050565b60008060408385031215613440578182fd5b82359150602083013561345281613b2d565b809150509250929050565b6000806040838503121561346f578182fd5b50508035926020909101359150565b600080600060608486031215613492578283fd5b505081359360208301359350604090920135919050565b600080600080600061014086880312156134c1578283fd5b8535945060208601359350604086013592506101208601878111156134e4578182fd5b94979396509194606001933592915050565b60008060006060848603121561350a578081fd5b8335925060208401359150604084013561352381613b3b565b809150509250925092565b60006020828403121561353f578081fd5b8135610a0a81613b3b565b60006020828403121561355b578081fd5b8151610a0a81613b3b565b6000815180845260208085019450808401835b83811015613597578151151587529582019590820190600101613579565b509495945050505050565b8060005b6006811015612e5e5781518452602093840193909101906001016135a6565b6000815180845260208085019450808401835b8381101561359757815163ffffffff16875295820195908201906001016135d8565b6004811061361857634e487b7160e01b600052602160045260246000fd5b9052565b6000825161362e818460208701613a73565b9190910192915050565b6080808252855190820181905260009060209060a0840190828901845b8281101561367157815184529284019290840190600101613655565b5050508381038285015261368581886135c5565b915050828103604084015261369a8186613566565b91505082606083015295945050505050565b6040815260006136bf60408301856135c5565b82810360208401526136d18185613566565b95945050505050565b60208152600082518060208401526136f9816040850160208701613a73565b601f01601f19169190910160400192915050565b60208082526016908201527543616e6e6f74206265207a65726f206164647265737360501b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600c908201526b2737ba1037b832b930ba37b960a11b604082015260600190565b6000610380820190506137e38284516135fa565b6020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015161381d60a08401826135a2565b5060c0830151610160818185015260e08501519150610180613841818601846135a2565b61010086015192506138576102408601846135a2565b6101208601516103008601526101408601516103208601529085015161034085015284015163ffffffff811661036085015290505092915050565b600082198211156138a5576138a5613b01565b500190565b600063ffffffff8083168185168083038211156138c9576138c9613b01565b01949350505050565b6000826138e1576138e1613b17565b500490565b60018163ffffffff825b808611156139245782820483111561390a5761390a613b01565b8086161561391757928202925b94851c94918002916138f0565b50509250929050565b600063ffffffff61394281851682851661394a565b949350505050565b60008261395957506001613a12565b8161396657506000613a12565b816001811461397c5760028114613986576139b7565b6001915050613a12565b60ff84111561399757613997613b01565b6001841b915063ffffffff8211156139b1576139b1613b01565b50613a12565b5060208310610133831016604e8410600b84101617156139ee575081810a63ffffffff8111156139e9576139e9613b01565b613a12565b6139f883836138e6565b8063ffffffff04821115613a0e57613a0e613b01565b0290505b92915050565b6000816000190483118215151615613a3257613a32613b01565b500290565b600082821015613a4957613a49613b01565b500390565b600063ffffffff83811690831681811015613a6b57613a6b613b01565b039392505050565b60005b83811015613a8e578181015183820152602001613a76565b83811115612e5e5750506000910152565b6000600019821415613ab357613ab3613b01565b5060010190565b600063ffffffff80831681811415613ad457613ad4613b01565b6001019392505050565b600063ffffffff80841680613af557613af5613b17565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b8015158114612ca257600080fd5b63ffffffff81168114612ca257600080fdfea264697066735822122077547adc4a7b4b359af97cf47079df381c8fbf53fb716eb838dd4f55b74530b664736f6c63430008040033000000000000000000000000dc4d748e2e368ccc3b0343e2ada95e47dd477cd100000000000000000000000023c9ca246b324c1491d01e9f30c5b6ce88e48335
Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)
000000000000000000000000dc4d748e2e368ccc3b0343e2ada95e47dd477cd100000000000000000000000023c9ca246b324c1491d01e9f30c5b6ce88e48335
-----Decoded View---------------
Arg [0] : _cakeTokenAddress (address): 0xdc4d748e2e368ccc3b0343e2ada95e47dd477cd1
Arg [1] : _randomGeneratorAddress (address): 0x23c9ca246b324c1491d01e9f30c5b6ce88e48335
-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 000000000000000000000000dc4d748e2e368ccc3b0343e2ada95e47dd477cd1
Arg [1] : 00000000000000000000000023c9ca246b324c1491d01e9f30c5b6ce88e48335
Age | Block | Fee Address | BC Fee Address | Voting Power | Jailed | Incoming |
---|