nCoinAge * 19 * 1000000 * 33 must be smaller than Int64 max (9223372036854775807) to avoid integer overflow! If the intermediate value gets larger than this, it will turn negative and the remaining calculation (/ (365 * 33 + 8)) will operate on the negative value.
This does not solve the general problem that nSubsidy as a whole might overflow, so an assert statement was added that checks for this case. Practically, this will not happen because it would only overflow at a coinAge of 1.77+14, or holding 1 billion coins for 485 years. ;)
Consensus effects
This patch will cause a hard fork because old clients will not accept staking transactions with high coinAge.
Relevant lines
Problem: Integer overflow in nSubsidy calculation
In the current phase,
COIN_YEAR_REWARD2
is being used.int64_t nSubsidy = nCoinAge * 19 * 1000000 * 33 / (365 * 33 + 8);
nCoinAge * 19 * 1000000 * 33
must be smaller than Int64 max (9223372036854775807) to avoid integer overflow! If the intermediate value gets larger than this, it will turn negative and the remaining calculation (/ (365 * 33 + 8)
) will operate on the negative value.If we do the math (see math section), we see that
nCoinAge = coins * ageInDays
coins * ageInDays < 14710322228
So, for example if a 40.3 million UTXO is older than 1 year, it will not be able to stake because an integer overflow will happen!
CreateCoinStake()
ConnectBlock()
For an 80 million UTXO, the threshold is just a half year etc..
Solution: Use CBigNum for intermediate values
This does not solve the general problem that nSubsidy as a whole might overflow, so an assert statement was added that checks for this case. Practically, this will not happen because it would only overflow at a coinAge of 1.77+14, or holding 1 billion coins for 485 years. ;)
Consensus effects
This patch will cause a hard fork because old clients will not accept staking transactions with high coinAge.
Appendix: Math for
nCoinAge = coins * ageInDays