Platform: Code4rena
Start Date: 29/03/2024
Pot Size: $36,500 USDC
Total HM: 5
Participants: 72
Period: 5 days
Judge: 3docSec
Total Solo HM: 1
Id: 357
League: ETH
Rank: 59/72
Findings: 1
Award: $8.28
🌟 Selected for report: 0
🚀 Solo Findings: 0
🌟 Selected for report: immeas
Also found by: 0xAkira, 0xCiphky, 0xGreyWolf, 0xJaeger, 0xMosh, 0xabhay, 0xlemon, 0xmystery, 0xweb3boy, Aamir, Abdessamed, Aymen0909, Breeje, DanielArmstrong, DarkTower, Dots, EaglesSecurity, FastChecker, HChang26, Honour, IceBear, JC, K42, Krace, MaslarovK, Omik, OxTenma, SAQ, Shubham, Stormreckson, Tigerfrake, Tychai0s, VAD37, ZanyBonzy, albahaca, arnie, ast3ros, asui, b0g0, bareli, baz1ka, btk, caglankaan, carrotsmuggler, cheatc0d3, dd0x7e8, grearlake, igbinosuneric, jaydhales, kaden, kartik_giri_47538, m4ttm, ni8mare, niser93, nonn_ac, oualidpro, pfapostol, pkqs90, popeye, radev_sw, samuraii77, slvDev, zabihullahazadzoi
8.2807 USDC - $8.28
function _getRedemptionAmount( uint256 ousgAmountBurned, uint256 price ) internal view returns (uint256 usdcOwed) { uint256 amountE36 = ousgAmountBurned * price; usdcOwed = _scaleDown(amountE36 / 1e18); }
The current implementation of the _getRedemptionAmount function divides amountE36 by 1e18 to scale down from a higher precision before subsequently multiplying by the decimalsMultiplier to adjust for the USDC decimal representation. This division prior to multiplication can result in a loss of precision due to Solidity's behavior of rounding down on division operations. To minimize this precision loss, it is recommended to perform all multiplications before divisions. This ensures that the division is the final operation, reducing the truncation of significant digits and providing users with a more accurate amount of USDC for their OUSG redemption.
Suppose a user redeems OUSG tokens when the price of OUSG is such that the precise USDC amount owed should be 100.5 USDC. In the current implementation:
ousgAmountBurned * price results in amountE36, a large number to maintain precision.
Dividing amountE36 by 1e18 truncates the decimal, reducing our example to 100 USDC (loss of 0.5 USDC due to rounding down).
The _scaleDown function further divides by decimalsMultiplier, potentially truncating more decimals.
By reversing the order and doing the multiplication by decimalsMultiplier before the division by 1e18, we could keep more of the fractional part before the final division, reducing the precision loss and giving the user a USDC amount closer to the precise 100.5 USDC. is this better
Manual reveiw
Consider implementing a more precise calculation method that minimizes rounding errors, such as using a higher precision for intermediate calculations or a different rounding strategy. Additionally, review other parts of the contract that perform similar calculations to ensure consistency and accuracy across the contract.
Math
#0 - c4-pre-sort
2024-04-05T02:54:46Z
0xRobocop marked the issue as duplicate of #246
#1 - c4-judge
2024-04-09T12:26:57Z
3docSec changed the severity to QA (Quality Assurance)
#2 - c4-judge
2024-04-09T12:27:33Z
3docSec marked the issue as grade-b