-
-
Notifications
You must be signed in to change notification settings - Fork 823
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
VIP: 'Bigmath' functions #1086
Comments
2**512 is astronomically big. It is much harder to make safety guarantees once you go down this path of multiple-register arthimitic. Do you have a use case you can point to that requires doing math that large? P.S. we have a decimals type. |
Sure, any time you want to do accounting precisely. Consider that ERC20 tokens typically have 18 decimal places (roughly 60 bits). Once you start wanting to trade at different prices, make partial fills, do ring trades, the issue of bit truncation starts to become important. Keep in mind, 2**256 is really big but we still check for overflow because not accounting for overflow results in bugs, and is an attack vector. This is just a generalization for more complex operations. |
Every arthimetic operation performed in Vyper is done by first validating it cannot overflow/underflow (reverting if it does), similar to the SafeMath library in common use on Solidity contracts. So that is not a concern. You are indeed correct that most ERC20 tokens use 18 decimal places as their default, mostly by convention. That leaves over 60 decimal places for the whole number portion, which is much larger than any reasonable project I've encountered. These numbers are large enough to be very, very precise for most reasonable use cases, but if you have a specific example for me to examine, I would like to see it. These data types are much larger than even what IEEE 64-bit floats can account for, and are much more precise because they are tracked as hard integers. |
Here is a use case we can study: https://github.com/compound-finance/compound-money-market You can deposit funds, maybe a few Ether, and you earn interest PER BLOCK. This might be closer to quantization errors than other projects. I believe adding functions to the standard library is always a huge deal. Instead, there should be a "contribs" package with all kinds of stuff like this. No need to justify adding something to contribs, just put it in. Then after the market clearly shows this is useful it gets added to the standard library. |
One use-case of big integer arithmetic is RSA Accumulator. |
IMO if Vyper is going to go down this path, you should consider instead just adding bigmath functions that use
You'd probably want to implement this via a library, similar to the in-Vyper RLP decoding feature. BTW if you want an efficient way to get the high order bits of 512-bit multiplication, one possible EVM-specific trick is something like |
@vbuterin Thanks for the feedback! I was unaware of the MODEXP precompile and it would probably be a better fit for RSA accumulation. In fact, exposing MODEXP as a library function could be a good thing to expose generally although we would need to think about the API to expose for such arbitrary-width integer types. BTW, the edge case you are looking for in the 512-bit multiplication is the Chinese remainder expression in the C code I added above - I tried to write it in a way which 'looks' like EVM code.
|
Another use case for |
Bigmath would be very useful for projects implementing bonding curves (linear and non-linear). In bonding curves, if the buy slope is very small, the token supply and the reserve can quickly become very large and the calculus required often involve to power 2 or power 3 these numbers. We are currently having the issue while implementing the continuous organization reference smart-contract. |
@thibaild checkout this file https://github.com/andytudhope/Recollections/blob/master/vyper/math/math.vy for a potential power function in vyper. |
Simple Summary
Add 'bigmath' functions which make it easier for contract authors to do more precise arithmetic.
Abstract
Add functions for dealing more precisely with overflow and underflow, especially where the implementations are not obvious. Specifically, a
bigmul
function which returns the result of multiplying two 256-bit uints as a pair of 256-bit uints (emulating a 512-bit uint), and abigdiv
function which returns the underflow portion of dividing the high word of a 512-bit uint into a 256-bit uint.Notes
bigadd
andbigsub
, but these are much more obvious for a contract author to implement.divmod
and/orbigmod
should be added to the mix.Motivation
Precise arithmetic is hard. For instance, the naive method to calculate multiplication by a fraction is subject to overflow attacks (consider 10 * 254/255 using 8-bit uints returns 0, instead of 9). Contract authors need a way to keep track of over and underflow without necessarily reaching for a full-fledged bignum implementation. Furthermore, efficient implementations (which take O(1) operations) are not obvious (the naive method being long multiplication or division). The two proposed functions provide a safe, efficient way to keep track of over and underflow, and in theory also provide enough machinery that higher-level abstractions like floating point arithmetic or bignum implementations could be built on top of them.
As an example, multiplying by a rational number could be implemented using these functions as follows:
Specification
Implement the following interface, either as builtin functions or as part of a 'standard library'.
The following C code can be taken as a suggestion of how to implement this efficiently.
Backwards Compatibility
Existing code may have collisions with the function names.
Copyright
Copyright and related rights waived via CC0
The text was updated successfully, but these errors were encountered: