-
-
Notifications
You must be signed in to change notification settings - Fork 128
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Incorrect hardcoded value of 0x8 in sqrt function (should be 0x4) #97
Comments
Hi @nonergodic, thanks for opening this issue. Would you mind explaining why we should use Re solc - as far as I remember, hardcoding the operations like I did was faster than using a for loop. But that was with the compiler that was available in 2021. It might be different now, I'm not sure. |
Because your own comment says: (Unrelated tangent: You're also using >= comparison, which might also be unnecessarily gas inefficient (there are only GT and EQ opcodes) depending on what optimizations solc is capable of... after all a >= hardocdedConstant is the same as A > hardcodedConstanst-1) there are other libraries that make the same mistake: notably, OpenZeppelin gets it right (though likely still somewhat gas inefficient): |
Thanks for explaining! Makes sense. It looks like @Amxx's PR addresses this issue. I think that the reason I haven't caught this in the tests is that I did not pass 4, 5, 6 or 7 as an input in the tests I've written for the The good news is that {4,5,6,7} in the number format used by PRBMath are tiny values, i.e. {4e-18, 5e-18, 6e-18, 7e-18}. The results were prone to have precision errors nonetheless, and they shouldn't have been a concern for most users. Re |
A couple of additional remarks: Looking at the code more closely, the comment is also (and still) wrong:
What it should say is:
The issue wasn't just for these values though, but also for all their left shifted variants. i.e. if you were to start out with e.g. 6 left shifted by 4 (i.e. 96 = 0x60), you'd compare with 0x10, find that 0x60 is larger, hence right shift xAux by 4 to 0x06 and left shift result by 2 from 1 to 4. Notice thought that even after the fix, you'll only end up with an initial guess of 8 and sqrt(96) > 9, so 8 is still not a power of 2 that is greater than or equal to sqrt(x). The (likely) reason why this issue didn't pop up during testing (and is of little consequence to users) is that it doesn't matter for small values because Heron's iteration is run 7x times anyway and so even a bad initial guess will converge to the right result. From here:
|
I cannot thank you enough for taking the time to report and explain this! I created an issue to track the fix for the comment: #103
Oh, but of course.
Makes sense. |
The hardcoded value here is wrong.
0x8 = 1<<3 but it should be 1<<2 i.e. 0x4
I'm not sure how smart solc is (whether it will unroll loops if one cranks the optimization runs sufficiently high - I haven't tried it yet), but all of this could be avoided by
The text was updated successfully, but these errors were encountered: