Precision loss can occur in defaultGaugePointFunction
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.
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.
Manual Review
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.
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.