Closed code423n4 closed 1 year ago
thereksfour changed the severity to 2 (Med Risk)
thereksfour marked the issue as primary issue
This is a good finding. I agree with medium severity because of highly unlikely scenario of deploying lottery with cool down period of 0, plus the way current oracles are working.
rand0c0des marked the issue as sponsor confirmed
thereksfour marked issue #343 as primary and marked this issue as a duplicate of 343
thereksfour marked the issue as satisfactory
Lines of code
https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/LotterySetup.sol#L114 https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/Lottery.sol#L135
Vulnerability details
Impact
A user can buy a ticket after the winning ticket was set by inserting the transaction in the same block, which allows them to win the jackpot. In addition, it allows for winning more than the intended jackpot amount.
Root-Cause
Buying tickets is blocked with the modifier
beforeTicketRegistrationDeadline
which reverts ifblock.timestamp
is larger thanticketRegistrationDeadline(drawId)
which isdrawScheduledAt(drawId) - drawCoolDownPeriod
The draw itself reverts if
block.timestamp < drawScheduledAt(currentDraw)
.This means that if
drawCoolDownPeriod
is0
(allowed by the constructor) andblock.timestamp
equalsdrawScheduledAt(currentDraw)
a ticket can be purchased in this block, even after the drawing happens.Result
This allows for someone to call
buyTickets
withcurrentDraw
and the winning ticket. If this is done also afterreceiveRandomNumber
is called (which in some random source implementation seems to be the case, as this is called from withinexecuteDraw
, or in the case the random number is also provided in the same block) thanwinAmount[drawFinalized][selectionSize]
is set to bedrawRewardSize(drawFinalized, selectionSize) / jackpotWinners;
so that each jackpot winner receives their share from the pot. The problem is that the tickets were purchased after this calculation, causing it to be not correct and allowing for the withdrawal of more funds than in the pot.Proof of Concept
Tools Used
Auditing
Recommended Mitigation Steps
Change
beforeTicketRegistrationDeadline
modifier to actually check it's before the registration deadline, i.e. make it like so: