The startLottery function is only callable by the Operator in order to start a new lottery round.
closeLottery - 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);
}
Callable by the Operator to close a round of the lottery.
drawFinalNumberAndMakeLotteryClaimable - 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 DEX 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 DEX 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 DEX to treasury address
cakeToken.safeTransfer(treasuryAddress, amountToWithdrawToTreasury);
emit LotteryNumberDrawn(currentLotteryId, finalNumber, numberAddressesInPreviousBracket);
}
For Operator to draw the final number using ChainLink VRF function.
In the case of tokens other than DEX mistakenly being sent to the lottery contract, this function is used to recover them and is only callable by the Owner
****
setMinAndMaxTicketPriceInCake - Owner
function setMinAndMaxTicketPriceInCake(uint256 _minPriceTicketInCake, uint256 _maxPriceTicketInCake)
external
onlyOwner
{
require(_minPriceTicketInCake <= _maxPriceTicketInCake, "minPrice must be < maxPrice");
minPriceTicketInCake = _minPriceTicketInCake;
maxPriceTicketInCake = _maxPriceTicketInCake;
}
To prevent the Operator setting the tickets to arbitrary prices during the event of a flash crash/pump.
setMaxNumberTicketsPerBuy - Owner
function setMaxNumberTicketsPerBuy(uint256 _maxNumberTicketsPerBuy) external onlyOwner {
require(_maxNumberTicketsPerBuy != 0, "Must be > 0");
maxNumberTicketsPerBuyOrClaim = _maxNumberTicketsPerBuy;
}
The Owner can modify the maximum number of tickets per transaction. This may be modified in the case of BSC block size increasing or decreasing.
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);
}
Function used to set the Operator, Treasury, and Injector addresses.
changeRandomGenerator - Owner
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);
}
For the Owner to update the RandomNumberGenerator contract in case we need to update the drawing logic, or release an update.