The variable totalFees
in PuppyRaffle::selectWinner
can overflow and the value of the totalFees
will be set to zero.
Checks for integer overflow and underflow are the default since the solidity version 0.8.0. But the PuppyRaffle.sol
contract uses solidity version ^0.7.6, therefore checks for overflow are required. In Solidity, an integer overflow occurs when the result of an arithmetic operation exceeds the maximum value that can be stored in the integer's bit representation. For instance, if we add 1 to the maximum value of uint256
(which is 2^256 - 1), an integer overflow occurs, and the result wraps around to 0.
In the selectWinner()
function, the line totalFees = totalFees + uint64(fee);
could potentially cause an overflow if totalFees
variable is already at its maximum value or the fee
variable has the maximum value of uint64
. If an overflow occurs, totalFees
would wrap around to 0.
If the totalFees
variable exceeds the maximum value a uint64
can hold, it could lead to incorrect calculations and lost fees.
Also, an integer overflow could potentially be exploited by an attacker. For example, if an attacker can control the fee
that is added to totalFees
, they might be able to cause an overflow and manipulate the contract's behavior.
Additionaly, in the withdrawFees()
function, the line require(address(this).balance == uint256(totalFees), "PuppyRaffle: There are currently players active!");
checks if the contract's balance equals totalFees
. If totalFees
overflows and wraps around to 0, this requirement will fail, and the function will revert with the message "PuppyRaffle: There are currently players active!"
. Because of that the function withdrawFees()
will not be able to withdraw any fees.
The following test demonstrates the integer overflow of totalFees
in the selectWinner()
function. It shows that a uint64 totalFees
value exceeds the maximum value a uint64
can hold without any errors, but the result is an integer overflow, where the uint64
value is set to 0. Add the test function testIntegerOverflowInSelectWinner()
to the file PuppyRaffleTest.t.sol
.
VS Code, Foundry
To prevent integer overflows in Solidity
, you can use Solidity 0.8
or later. From Solidity 0.8
onwards, the compiler includes built-in overflow and underflow checks. If an overflow or underflow occurs during an arithmetic operation, the operation will fail and the transaction will revert.
Another way to mitigate an overflow is to use SafeMath
library that provide safe arithmetic operations that check for overflows and underflows before executing the operation. If an overflow is detected, the function will revert the transaction.
Also, after performing an arithmetic operation, you can check if an overflow occurred and handle it appropriately.
Here's an example of how you might use SafeMath
to prevent integer overflows:
This function the add
function from the SafeMath
library is used to add two numbers. If an overflow occurs, the function will revert the transaction.
The contest is live. Earn rewards by submitting a finding.
This is your time to appeal against judgements on your submissions.
Appeals are being carefully reviewed by our judges.