The lesPay
token sale model uses service tokens that continuously "expire" under certain conditions, meaning their value is reduced exponentially over time. Expiration happens when some amount of free connection is possible and therefore all existing tokens are spendable. Expiration can be interpreted as a kind of "spendability" fee that incentivizes clients to indeed spend their tokens in a limited time frame. This can be realized in two ways:
- with "inflationary" units; if all prices rise exponentially then value of existing tokens is reduced inversely
- with "stable tokens"; if the nominal value of each token is stable then the token balances should be reduced continuously
The second interpretation fits with the model better because service tokens (which are basically a promise from the server) are meant to have a more or less predictable purchasing power. With stable token nominations the client can expect the prices to not change quickly which is a reasonable expectation after buying service tokens.
On the other hand, the inflationary model is easier to handle technically because it does not require regularly updating all balance amounts (both in memory and database) throughout the system. This is what expiredValue
implements; it stores values internally in an inflationary format but allows adding and retrieving values in stable format. It assumes a global logOffset
value that accumulates token expiration and is basically the logarithm of the exchange rate between "stable" and "inflationary" units.
Ideally, the conversion would be very simple:
expiredValue = tokenAmount*e^logOffset
tokenAmount = expiredValue*e^(-logOffset)
A little trick is required though in order to avoid numerical problems. Since logOffset
grows monotonically throughout the lifetime of the system, the exchange rate can grow very big. This could be an ideal use case for floating point arithmetics but unfortunately even float64
could overflow eventually. This is why expiredValue
is made of a 64 bit base value and a 64 bit exponent. The "inflationary" amount can be calculated as base * 2^exp
. Negative numbers and fractional parts are not needed here so both are non-negative. logOffset
is a fixed-point value which can be interpreted either as a 2-base or a natural logarithm by using different multiplier constants (either logMultiplier
or log2Multiplier
). The conversion rate from stable to inflationary is therefore e^(logOffset/logMultiplier)
. Calculating this value directly as a float64
would still not avoid overflow though, so we calculate the base and exponent separately by splitting logOffset
to integer and fractional parts (interpreted as base 2 this time):
logint = uint64(logOffset / log2Multiplier) // since log2Multiplier = 2^24, this is the higher 40 bits of logOffset
logfrac = logOffset % log2Multiplier // this is the lower 24 bits of logOffset
Then we can use logint
directly as the exponent for expiredValue
while the exponential of logfrac
can be calculated as floating point (this time interpreted as a natural logarithm in order to be able to use floating point exponential function):
expiredValue.base = uint64(tokenAmount*math.Exp(float64(logfrac)/logMultiplier))
expiredValue.exp = logint