Blast the balloon SC Audit
For a user to claim his cumulated prizes prizes, he must call the claimPrize function.
This function does not allow users to withdraw any potential rewards from the current game round. This check, however, is incorrectly implemented and a user can call the function and get the pending rewards exactly at the end time of the round. This can be done due to including equality in the round time check.
A round is defined as starting from Round.startTime and continuing up to, and including the Round.startTime + Round.duration. This means that any pending spins that do execute exactly at the Round.startTime + Round.duration timestamp are considered valid.
The issue with the claimPrize function is that it incorrectly considers the end time, which is a valid round time, to be out of a round block.timestamp >= roundInfo.startTime + roundInfo.duration and allows rewards from the current round to be withdrawn.
An attacker that already has a winning position can also exploit this issues to have a chance at doubling his rewards as such:
claimPrize function at the end of the round timeentropyCallback function calls) that are done after the claimPrize execution can:
If either during an extension or exactly then, any of the prizes held by the attacker are to change hands, then the new owner (either the attacker himself or a normal users who's organic transactions happen to execute as such) would also benefit from the prize. Initially the second holder would not be able to withdraw due to a lack of funds in the contract. But after a new round is started, funds are send in the contract and the reward can be extracted again.
The getClaimableAmount function, used for estimating claimable amounts, also has this issue.
Change the comparison in the if code to > instead of >= when checking if the round has ended in the claimPrize and getClaimableAmount functions.
Blast the balloon SC Audit