As per the docs:
Referrer rewards are allocated on a per draw basis
Referrers who meet the minimum referral requirement according to the following table will be eligible for the Individual Referrer Allocation
The minimum referral requirement for a draw N + 1 is computed based on the number of tickets sold for the draw N.
In the code, this is computed upon draw execution of the draw N.
In receiveRandomNumber():
src/Lottery.sol
224: winningTicket[drawFinalized] = _winningTicket;
225: drawExecutionInProgress = false;
226:
227: uint256 ticketsSoldDuringDraw = nextTicketId - lastDrawFinalTicketId;
228: lastDrawFinalTicketId = nextTicketId;
229: // solhint-disable-next-line max-line-length
230: referralDrawFinalize(drawFinalized, ticketsSoldDuringDraw);
The number used as βnumber of tickets sold for the draw Nβ is ticketsSoldDuringDraw. It is computed as nextTicketId - lastDrawFinalTicketId.
The issue is that nextTicketId is the id of the last Ticket minted. But tickets are minted for every draw, and ticketId is incremented on mint(), regardless of the drawId
src/Ticket.sol
23: function mint(address to, uint128 drawId, uint120 combination) internal returns (uint256 ticketId) {
24: ticketId = nextTicketId++; //@audit - not a function of drawId
25: ticketsInfo[ticketId] = TicketInfo(drawId, combination, false);
26: _mint(to, ticketId);
27: }
This means ticketsSoldDuringDraw accounts for tickets sold during the draw N, notfor it.
The minimum referral requirement maths is completely broken, and will lead to a potential loss of rewards for referrers.
let us look at a draw N.
Before execution, lastDrawFinalTicketId == X.
Execution now happens.
Between the last draw execution and this one, there was a specifically high number of ticket sales, for draws ranging from N to M: assume 5,000 were sold for draw N, but 50,000 were sold in total.
ticketsSoldDuringDraw = nextTicketId - lastDrawFinalTicketId = 50,000
The minimum referral amount is computed:
src/ReferralSystem.sol
93: minimumEligibleReferrals[drawFinalized + 1] =
94: getMinimumEligibleReferralsFactorCalculation(ticketsSoldDuringDraw);
Because 50,000 tickets were sold, the minimum number of referrals for draw N + 1 will be 0,75% * 50,000 = 375, while it should have been 5,000 * 1% = 50.
Referrers for draw N + 1 will need to find 325 more referrers than what they should.
Some referrers will lose on the reward they were entitled to (if their referral amount is between 50 and 375).
Manual Analysis
Use a mapping for nextTicketId in Ticket, so that it accounts for the drawId
The text was updated successfully, but these errors were encountered:
All reactions