DeFiHardhat
21,000 USDC
View results
Submission Details
Severity: medium
Invalid

Precision Loss in `getPenalizedUnderlying` Function Due to Division Before Multiplication

Summary

During our security audit of the smart contract, we identified a precision loss issue in the getPenalizedUnderlying function. The function calculates the amount of Ripe Tokens redeemable after a Chop operation on Unripe Tokens. The current implementation performs division operations before multiplication, leading to potential underestimation of the redeem value due to integer division in Solidity.

Vulnerability Details

The critical part of the function where the issue occurs is:

redeem = underlyingAmount.mul(s.recapitalized).div(totalUsdNeeded).mul(amount).div(supply);

In Solidity, division operations round down to the nearest integer, which can cause significant precision loss when the divisor is much larger than the dividend. Since totalUsdNeeded and supply could be large numbers, performing division before multiplication reduces the resulting redeem value more than expected.

Impact

The precision loss in the redeem calculation could lead to an unfair distribution of Ripe Tokens. Users participating in the Chop operation might receive fewer tokens than they are entitled to, which could lead to dissatisfaction and distrust in the platform's tokenomics. This issue fundamentally affects the fairness and accuracy of token distributions within the contract's economic model.

Tools Used

  • Manual Review: Detailed line-by-line examination of the contract's logic and calculations.

Recommendations

Adjust Calculation Order to Minimize Precision Loss

To mitigate the issue and reduce the impact of precision loss, we recommend restructuring the calculation to delay division operations as much as possible. This can be achieved by aggregating all multiplication operations first and then performing the division:

// Aggregate all multiplications first
uint256 numerator = underlyingAmount.mul(s.recapitalized).mul(amount);
// Perform division at once
redeem = numerator.div(totalUsdNeeded.mul(supply));

This adjustment ensures that the intermediate results are kept as large as possible before the division, minimizing the rounding errors due to integer arithmetic in Solidity. This change should be tested thoroughly to ensure it behaves as expected without introducing new issues.

Updates

Lead Judging Commences

giovannidisiena Lead Judge about 1 year ago
Submission Judgement Published
Invalidated
Reason: Known issue

Support

FAQs

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