Open c4-bot-6 opened 7 months ago
I would consider this QA to ensure to add a require check that maxPrizeCount
cannot be decreased as that is the intention
That's indeed a much simpler fix!
I would still say Medium severity is appropriate seeing as that could not have been inferred from the audit scope and given the potential impact, but either way I'll accept the judge's decision.
0xleastwood marked the issue as satisfactory
0xleastwood marked the issue as primary issue
jooleseth (sponsor) confirmed
0xleastwood marked the issue as selected for report
Lines of code
https://github.com/code-423n4/2024-02-thruster/blob/3896779349f90a44b46f2646094cb34fffd7f66e/thruster-protocol/thruster-treasure/contracts/ThrusterTreasure.sol#L139-L142 https://github.com/code-423n4/2024-02-thruster/blob/3896779349f90a44b46f2646094cb34fffd7f66e/thruster-protocol/thruster-treasure/contracts/ThrusterTreasure.sol#L102-L120
Vulnerability details
Impact
The
ThrusterTreasure
contract is designed to manage rounds of a lottery game, where participants can enter tickets and claim prizes based on random draws. The contract includes a variablemaxPrizeCount
which dictates the maximum number of prizes that can be set for any given round. This variable can be modified by the contract owner at any time through thesetMaxPrizeCount(uint256 _maxPrizeCount)
function:ThrusterTreasure.sol#L139-L142
The issue arises when
maxPrizeCount
is decreased after prizes for a round have been set but before they have been claimed. Since theclaimPrizesForRound(uint256 roundToClaim)
function iterates over prize indices up tomaxPrizeCount
, reducing this count means that winners of prizes with indices higher than the newmaxPrizeCount
will be unable to claim their winnings:ThrusterTreasure.sol#L102-L120
This could lead to a scenario where legitimate winners are denied their prizes due to a change in contract state that is unrelated to the rules of the game or their actions. Moreover, since calling
claimPrizesForRound()
clears the user's entries for the round, revertingmaxPrizeCount
to its previous state does not allow them to claim the remaining tickets. This means they will effectively never be able to claim their prize.Proof of Concept
maxPrizeCount
to 5 and configures five prizes for a given round.maxPrizeCount
to 3 for the next round.claimPrizesForRound(uint256 roundToClaim)
function now iterates only up to the newmaxPrizeCount
of 3.Tools Used
Manual review
Recommended Mitigation Steps
To address this issue, implementing a checkpoint pattern for the
maxPrizeCount
variable is suggested. This method involves tracking changes tomaxPrizeCount
with checkpoints that record the value and the round number when the change occurs.A possible implementation could look like this:
This change ensures that each round's prize structure is fixed upon the round's creation, preventing post-hoc alterations that could negatively impact participants. Note that this implementation still requires attention is paid to not calling
setMaxPrizeCount()
for a given round if prizes have already been set for higher indices.Assessed type
Other