Fixed#safeMulDiv rounds incorrect when rounding mode is set to ROUND #64
Labels
bug
Something isn't working
downgraded by judge
Judge downgraded the risk level of this issue
grade-a
primary issue
Highest quality submission among a set of duplicates
Q-08
QA (Quality Assurance)
Assets are not at risk. State handling, function incorrect as to spec, issues with clarity, syntax
🤖_primary
AI based primary recommendation
sponsor confirmed
Sponsor agrees this is a problem and intends to fix it (OK to use w/ "disagree with severity")
sufficient quality report
This report is of sufficient quality
Lines of code
https://github.com/code-423n4/2024-07-reserve/blob/3f133997e186465f4904553b0f8e86ecb7bbacbf/contracts/libraries/Fixed.sol#L561-L607
Vulnerability details
Impact
Fixed#safeMulDiv rounds incorrect when rounding mode is set to ROUND and functions closer to CEIL
Proof of Concept
For rounding to be accurate the unmodified divisor must be used to check the remainder of the division. Above we see that c_256 is divided by pow2 before being used to check mm (the remainder). Take the following example of c = 1e18:
pow2 = c & (0 - c) = 1000000000000000000 & (0 - 1000000000000000000) = 524288
c_256 = c_256/524288 = 19073486328125
As we can see the final c_256 is significantly lower than it should be. In this scenario, values greater than 499999999999999999 should be rounded up however, due to the error in implementation, values greater than 9536743164062 will be rounded up. To put that in decimal terms, that is 0.499999999999999999 vs 0.000009536743164062 which is a staggering difference. This effectively turns ROUND into CEIL.
Although safeMulDiv is not used with the ROUND rounding in the in-scope contracts, this math library is used across the entire protocol and will presumably be used during future upgrades as well.
We all know that rounding error, although they seems insignificant have lead to some very nasty exploits in defi. Any future update which utilizes this function to round for distribution of asset, pricing or share evaluation could cause loss of funds. In such situation, the incorrect rounding direction could cause incremental advantage to an attacker who could repeatedly exploit the rounding error to drain funds from the protocol. This risk is exponentially greater due to these contracts being deployed on low cost chains like base and OP.
Tools Used
Forge fuzz testing
Recommended Mitigation Steps
Use c rather than c_256 for checking the round:
Assessed type
Error
The text was updated successfully, but these errors were encountered: