Unsafe casting in RewardsDistributorV2 leads to incorrect reward distribution
Summary
Solidity does not revert when casting a negative number to an unsigned integer (uint). Instead, it underflows to a large number.
This behavior can lead to incorrect reward distribution in the RewardsDistributorV2 contract when the calculated balance is negative.
Vulnerability Detail
In the _claim function, the balance of a token to be distributed is calculated as follows:
uint balance_of = Math.max(uint(int256(old_user_point.bias - dt * old_user_point.slope)), 0);
The intention is to return zero when the calculated balance is a negative number.
However, due to Solidity's behavior, casting a negative number to uint underflows to a large number. This can lead to incorrect reward calculations.
Impact
This issue can result in:
Potentially large, unintended reward payouts.
Incorrect reward distribution if third-party protocols depend on this function.
Errors in further updates or functionalities that rely on this codebase.
To address this issue, Math.max should be used before casting a negative number to uint to ensure that the balance is not negative. This will prevent underflow and ensure that the reward distribution is accurate.
blackhole
High
Unsafe casting in
RewardsDistributorV2
leads to incorrect reward distributionSummary
Solidity does not revert when casting a negative number to an unsigned integer (uint). Instead, it underflows to a large number. This behavior can lead to incorrect reward distribution in the
RewardsDistributorV2
contract when the calculated balance is negative.Vulnerability Detail
In the _claim function, the balance of a token to be distributed is calculated as follows:
uint balance_of = Math.max(uint(int256(old_user_point.bias - dt * old_user_point.slope)), 0);
The intention is to return zero when the calculated balance is a negative number. However, due to Solidity's behavior, casting a negative number to uint underflows to a large number. This can lead to incorrect reward calculations.Impact
This issue can result in:
Code Snippet
https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/RewardsDistributorV2.sol#L139 https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/RewardsDistributorV2.sol#L158 https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/RewardsDistributorV2.sol#L208 https://github.com/sherlock-audit/2024-06-velocimeter/blob/main/v4-contracts/contracts/RewardsDistributorV2.sol#L265
Tool used
Manual Review
Recommendation
To address this issue, Math.max should be used before casting a negative number to uint to ensure that the balance is not negative. This will prevent underflow and ensure that the reward distribution is accurate.