Closed code423n4 closed 1 year ago
0xRobocop marked the issue as primary issue
0xRobocop marked the issue as sufficient quality report
May be QA.
Description lacks detail in quantifying how many tokens are lost due to this error. In my experience, these types of errors are negligible.
ishaansinghal (sponsor) disputed
We do the multiplication operation first since the numerator, denominator, and result are in 1e18 format. Consider y0 was 1.5 x 10^18 and util was 1 x 10^18. Performing the division first would erase the decimal in the result.
JustDravee marked the issue as unsatisfactory: Invalid
Lines of code
https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L750 https://github.com/code-423n4/2023-08-shell/blob/c61cf0e01bada04c3d6055acb81f61955ed600aa/src/proteus/EvolvingProteus.sol#L781
Vulnerability details
Impact
Swaps and Deposits work with two tokens X and Y. The computed amount of tokens on the receiving end decrease due to this multi-statement loss of precision occurring due to division before multiplication.
Note: This finding is different from the [L-06] bot finding due to two reasons: 1. The bot finding in the first place is not a division before multiplication issue. 2. This issue is due to loss of precision occurring across three statements.
Proof of Concept
In the equations below, u = utility ac = a_convert bc = b_convert M = MULTIPLIER (Rest of the symbols are self explanatory according to the current implementation in function _getPointGivenYandUtility(). The following applies to _getPointGivenXandUtility() function as well but we'll be talking about _getPointGivenYandUtility() function here).
The loss of precision occurs here due to division occurring before multiplication across the three statements below. If we take a look at this simplified equation (represents internal calculations of Lines 781-783) for f_2, we can see division occurs before multiplication on step 4: https://drive.google.com/file/d/1qVgf9ycl4tnCrRR1TR19WIt47YM-xHpd/view
This leads to the return value f_2 (aka x0 in _getPointGivenYandUtility()) being smaller than expected. The deviance or loss of precision of the current three-step implementation above can be compared to the simplified equation (present on the last line of the image).
Here is the coded POC, which compares loss of precision of the simplified equation with the current three-step implementation:
EvolvingProteusProperties.t.sol
fileforge test --match-test testLossOfPrecisionDifference
In the test, we can see that
assertLt(x0, f_2);
passes meaning that the loss of precision is greater in the current three-step implementation than the simplified equation on the last line of the image.Tools Used
Manual Review
Recommended Mitigation Steps
The solution is the simplified equation on the last line of the image.
The following changes below are done with respect to the _getPointGivenYandUtility() function. The same can be done for the _getPointGivenXandUtility() function.
Solution:
Assessed type
Other