Incorrect type casting of int8
to uint8
in the withdraw
function can lead to unexpected large values, causing potential calculation errors and unfair reward distribution.
The withdraw
function in the ThePredicter
contract uses uint8(score)
to cast an int8
score to a uint8
. If the score is negative, this conversion results in an unexpected large value due to the two's complement representation of negative numbers in binary form. This can cause incorrect reward calculations and potential manipulation of scores.
The issue is in this function:
https://github.com/Cyfrin/2024-07-the-predicter/blob/main/src/ThePredicter.sol#L111-L144
The problem is in this line: uint256 shares = uint8(score);
Proof of Concept (PoC):
Consider the following example:
If score is -1 (binary 11111111 in int8):
Casting -1 to uint8 results in 255.
If score is -5 (binary 11111011 in int8):
Casting -5 to uint8 results in 251.
This casting can lead to incorrect reward calculations and unfair distribution.
Incorrect Reward Calculation
: The withdraw
function may distribute incorrect rewards due to the misinterpreted scores.
Potential Manipulation
: Malicious actors can exploit this to receive higher rewards than they are eligible for.
Manual Review
Ensure that the score is non-negative before casting it to an unsigned integer type. Use a require statement to enforce this:
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.