Open charles-cooper opened 4 years ago
I don't think that you should have to specify the amount of bits the type takes up. We can calculate that.
It would be really nice if we have the ability to create custom types (or type aliases) such that we could allow typing to be used by end users more directly, e.g. ray := decimal(places=27)
for Maker codebase.
Note: 38 decimal places is the most possible that can fit in 128 bits (corresponding to fixed255x38
)
List of decimals:
fixed132x1
fixed135x2
fixed138x3
fixed142x4
fixed145x5
fixed148x6
fixed152x7
fixed155x8
fixed158x9
fixed162x10
fixed165x11
fixed168x12
fixed172x13
fixed175x14
fixed178x15
fixed182x16
fixed185x17
fixed188x18
fixed192x19
fixed195x20
fixed198x21
fixed202x22
fixed205x23
fixed208x24
fixed212x25
fixed215x26
fixed218x27
fixed222x28
fixed225x29
fixed228x30
fixed231x31
(NOTE: doesn't fit pattern)fixed235x32
fixed238x33
fixed241x34
(NOTE: doesn't fit pattern)fixed245x35
fixed248x36
fixed251x37
(NOTE: doesn't fit pattern)fixed255x38
Meeting notes: Pamp it
Was thinking about this some more today. It could be something like the following:
Decimal
type, which is a fixed point type that is allowed to be any width decimal (using fixed<M>x<N>
notation) as long as the calculations align at "endpoints" (internal type conversions or ABI boundaries)Decimal
takes an argument (e.g. Decimal(fixed168x10)
) which defines the "required" shape of the Decimal
type at that interface and pins that boundary to that particular ABI typeDecimal
and uses fixed<M>x<N>
notation to denote that interface type. This can be overriden using the same trick for interface definitions e.g. def myCall(val: Decimal(fixed168x10))
to pin to a particular type (useful for ERCs)This design would be strictly better than doing uint256 math all over, with implicit assumptions about precision loss, and occasionally watching contract call failures from using SafeMath without due consideration to these scenarios. The compiler can also produce suggestions for the min/max size particular values can be at conversion boundary points in order to ensure correct operation of the algorithm.
meeting notes: add an example, bring up for discussion again
Simple Summary
Allow generic decimal types with parametrizable precision and bits settings.
Motivation
Fixed point math is generally useful for smart contracts as one of the most common use cases for smart contracts is to do accurate accounting. This is manifest in the fact that numerous ERCs and applications depend on fixed point math (ex. ERC20, various AMMs, ERC4626). This VIP proposes general decimal types which are
Specification
Introduce new PEP484 style
Decimals
andUDecimals
types which each accept two parameters (the latter of which is optional).Examples:
UDecimals[18]
(i.e. unsigned decimals type with 18 decimals of precision and occupying 256 bits of space)UDecimals[18, 128]
(i.e. unsigned decimals with 18 decimals of precision and occupying 128 bits of space)Decimals[10, 168]
(equivalent to current decimals)The existing
decimals
type will be considered a deprecated alias ofDecimals[10, 168]
.In general, the ABI type of
Decimals[N, B]
will beint_<B>
. The ABI type ofUDecimals[N, B]
will beuint_<B>
.Backwards Compatibility
decimal
typedecimal
.Dependencies
Requires some refactoring of the internal type system (probably will be done as work for #2431).
References
https://github.com/vyperlang/vyper/issues/3039 Could be useful for use-site tuning of ERC20 or other token libraries.
Copyright
Copyright and related rights waived via CC0