DeFiHardhatOracleProxyUpdates
100,000 USDC
View results
Submission Details
Severity: low
Invalid

Precision loss can occur in defaultGaugePointFunction

Summary

Precision loss can occur in defaultGaugePointFunction

Vulnerability Details

Consider a simplified code where ONE_POINT represents 1 gauge point with a precision of 18 decimals. :

contract PrecisionDemo {
using SafeMath for uint256;

uint256 private constant ONE_POINT = 1e18;

function simulatePrecisionIssue(uint256 currentGaugePoints, uint256 percentOfDepositedBdv) external pure returns (uint256 newGaugePoints) {
    // Simulating precision loss without fixed-point arithmetic
    newGaugePoints = currentGaugePoints.add(ONE_POINT.mul(percentOfDepositedBdv).div(100));
}

}

We then attempt to calculate a new gauge point value based on a percentage of deposited BDV. Now, by simulating a precision issue by calling the function with a small percentage that doesn't evenly divide 100:

uint256 currentGaugePoints = 100e18; // Starting gauge points
uint256 percentOfDepositedBdv = 0.01e18; // 0.01% of deposited BDV

PrecisionDemo contractInstance = new PrecisionDemo();
uint256 newGaugePoints = contractInstance.simulatePrecisionIssue(currentGaugePoints, percentOfDepositedBdv);

The attempting to increase the gauge points by 0.01% here will not give the expected result due to lack of fixed point arithmetic. Without proper scaling, rounding errors may occur, leading to imprecise calculations.

Impact

The attempting to increase the gauge points by 0.01% here will not give the expected result due to lack of fixed point arithmetic. Without proper scaling, rounding errors may occur, leading to imprecise calculations.

Tools Used

Manual Review

Recommendations

A fixed point math library import(as SafeMath primarily handles on overflow and underflow issues) can remediate this issue or introduction of a scaling factor.
Consider this modification:
// Assume we have a contract with a similar structure
contract PrecisionDemo {
using SafeMath for uint256;

uint256 private constant ONE_POINT = 1e18;

function simulatePrecisionIssue(uint256 currentGaugePoints, uint256 percentOfDepositedBdv) external pure returns (uint256 newGaugePoints) {
    // Scaling factor (e.g., 1e6 for 6 decimal places)
    uint256 scalingFactor = 1e6;

    // Scale the percentage value to work within the integer realm
    uint256 scaledPercent = percentOfDepositedBdv.mul(scalingFactor).div(100);

    // Simulating precision loss with proper scaling
    newGaugePoints = currentGaugePoints.add(ONE_POINT.mul(scaledPercent).div(scalingFactor));
}

}
After introducing the scaling factor, the percentOfDepositedBdv value is then scaled by multiplying it with the scalingFactor and dividing by 100. This brings it into the integer realm with the desired precision. Arithmetic operations are performed using the scaled values. We then divide by the scalingFactor to compensate for the scaling in the final result.

Updates

Lead Judging Commences

giovannidisiena Lead Judge over 1 year ago
Submission Judgement Published
Invalidated
Reason: Incorrect statement
Assigned finding tags:

Gauge point precision

Support

FAQs

Can't find an answer? Chat with us on Discord, Twitter or Linkedin.