Attacker can run executeDraw() in Lottery.sol, receive random numbers and than buy tickets with known numbers in one block.
Harm: Jackpot
Proof of Concept
This vulnerability is possible to use when contract has been deployed with COOL_DOWN_PERIOD = 0;
The executeDraw() allows to be called at the last second of draw due to an incorrect comparison block.timestamp with drawScheduledAt(currentDraw), what is start of draw.
function executeDraw() external override whenNotExecutingDraw {
// slither-disable-next-line timestamp
if (block.timestamp < drawScheduledAt(currentDraw)) { //@dingo should be <= here
revert ExecutingDrawTooEarly();
}
returnUnclaimedJackpotToThePot();
drawExecutionInProgress = true;
requestRandomNumber();
emit StartedExecutingDraw(currentDraw);
}
Also modifier in LotterySetup.sol allows same action:
modifier beforeTicketRegistrationDeadline(uint128 drawId) {
// slither-disable-next-line timestamp
if (block.timestamp > ticketRegistrationDeadline(drawId)) { //@dingo should be >= here
revert TicketRegistrationClosed(drawId);
}
_;
}
Exploit:
-Attacker is waiting for last second of PERIOD (between to draws).
-Call executeDraw(). It will affect at requestRandomNumber() and chainlink will return random number to onRandomNumberFulfilled() at RNSourceController.sol.
-Attacker now could read received RandomNumber:
Lines of code
https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/Lottery.sol#L135 https://github.com/code-423n4/2023-03-wenwin/blob/91b89482aaedf8b8feb73c771d11c257eed997e8/src/LotterySetup.sol#L114
Vulnerability details
Impact
Attacker can run
executeDraw()
inLottery.sol
, receive random numbers and than buy tickets with known numbers in one block. Harm: JackpotProof of Concept
This vulnerability is possible to use when contract has been deployed with COOL_DOWN_PERIOD = 0; The
executeDraw()
allows to be called at the last second of draw due to an incorrect comparisonblock.timestamp
withdrawScheduledAt(currentDraw)
, what is start of draw.Also modifier in LotterySetup.sol allows same action:
Exploit: -Attacker is waiting for last second of
PERIOD
(between to draws). -CallexecuteDraw()
. It will affect atrequestRandomNumber()
and chainlink will return random number toonRandomNumberFulfilled()
atRNSourceController.sol
. -Attacker now could read received RandomNumber:Attacker buy new ticket with randomNumber:
-Claim winnings:
Exploit code:
Tools Used
VScode and manual review.
Recommended Mitigation Steps
1) Change
<
by<=
:2) Change
>
by>=
: