This repository has been archived by the owner on Aug 30, 2022. It is now read-only.
Prevent overflow within claimrewards in cases of extreme inflation - develop #328
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Change Description
Now that it is possible to set the inflation rate using the
setinflation
action, the operators of the network could in theory set the annual inflation rate to an extremely large number. In such a case (and with a large current supply) it is possible for thenew_tokens
amount calculated withineosio::claimrewards
to overflow into a negative number. Then due to howto_per_block_pay
andto_per_block_pay
are calculated usinguint128_t
intermediate variables before being cast toint64_t
, those two amounts could end up with garbage (possibly negative values).The following code demonstrates how such values could be computed in these extreme situations:
Since
new_tokens
is negative, none of theissue
ortransfer
inline actions will execute, but thepervote_bucket
andperblock_bucket
fields of the global state will be modified with the calculated garbage values.To prevent this possibility from occurring, the code should check for the overflow and stop proceeding forward if encountered.
So this PR avoids immediately converting the
double
representation of the computed new tokens amount (calledadditional_inflation
now in the code) into anint64_t
. Instead, it first comparesadditional_inflation
against the largest double-precision floating point number that can be represented by aint64_t
without any loss of precision. Ifadditional_inflation
is not greater than this limit, then it is converted into anint64_t
and stored asnew_tokens
before proceeding forward.Furthermore, though this should never have occurred anyway as long as the invariant that
_gstate4.continuous_rate >= 0
is maintained, extra precaution is taken to ensure that floating-point arithmetic approximations could not possibly lead to a negative value fornew_tokens
(which if possible could again modifyto_per_block_pay
andto_per_vote_pay
in unintended ways).This PR also adds a new test case,
eosio_system_tests/extreme_inflation
, which triggers the above mentioned scenario to ensure the new check protects against possible corruption of the system contract tables.Deployment Changes
API Changes
Documentation Additions