Skip to content
This repository has been archived by the owner on Aug 30, 2022. It is now read-only.

Commit

Permalink
Merge pull request #328 from EOSIO/extreme-inflation-develop
Browse files Browse the repository at this point in the history
Prevent overflow within claimrewards in cases of extreme inflation - develop
  • Loading branch information
arhag authored Sep 9, 2019
2 parents 0548294 + 6da7bec commit 9cc4dcd
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 1 deletion.
5 changes: 4 additions & 1 deletion contracts/eosio.system/src/producer_pay.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,10 @@ namespace eosiosystem {
const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill).count();

if( usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point() ) {
int64_t new_tokens = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year);
double additional_inflation = (_gstate4.continuous_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year);
check( additional_inflation <= double(std::numeric_limits<int64_t>::max() - ((1ll << 10) - 1)),
"overflow in calculating new tokens to be issued; inflation rate is too high" );
int64_t new_tokens = (additional_inflation < 0.0) ? 0 : static_cast<int64_t>(additional_inflation);

int64_t to_producers = (new_tokens * uint128_t(pay_factor_precision)) / _gstate4.inflation_pay_factor;
int64_t to_savings = new_tokens - to_producers;
Expand Down
37 changes: 37 additions & 0 deletions tests/eosio.system_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1525,6 +1525,43 @@ BOOST_FIXTURE_TEST_CASE(change_inflation, eosio_system_tester) try {

} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_CASE(extreme_inflation) try {
eosio_system_tester t(eosio_system_tester::setup_level::minimal);
symbol core_symbol{CORE_SYM};
t.create_currency( N(eosio.token), config::system_account_name, asset((1ll << 62) - 1, core_symbol) );
t.issue( asset(10000000000000, core_symbol) );
t.deploy_contract();
t.produce_block();
t.create_account_with_resources(N(defproducera), config::system_account_name, core_sym::from_string("1.0000"), false);
BOOST_REQUIRE_EQUAL(t.success(), t.regproducer(N(defproducera)));
t.transfer( config::system_account_name, "defproducera", core_sym::from_string("200000000.0000"), config::system_account_name);
BOOST_REQUIRE_EQUAL(t.success(), t.stake("defproducera", core_sym::from_string("100000000.0000"), core_sym::from_string("100000000.0000")));
BOOST_REQUIRE_EQUAL(t.success(), t.vote( N(defproducera), { N(defproducera) }));
t.produce_blocks(4);
t.produce_block(fc::hours(24));

BOOST_REQUIRE_EQUAL(t.success(), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera")));
t.produce_block();
asset current_supply;
{
vector<char> data = t.get_row_by_account( N(eosio.token), core_symbol.to_symbol_code().value, N(stat), core_symbol.to_symbol_code().value );
current_supply = t.token_abi_ser.binary_to_variant("currency_stats", data, eosio_system_tester::abi_serializer_max_time)["supply"].template as<asset>();
}
t.issue( asset((1ll << 62) - 1, core_symbol) - current_supply );
BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(std::numeric_limits<int64_t>::max(), 50000, 40000));
t.produce_block();

t.produce_block(fc::hours(10*24));
BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera")));

t.produce_block(fc::hours(11*24));
BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("magnitude of asset amount must be less than 2^62"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera")));

t.produce_block(fc::hours(24));
BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("overflow in calculating new tokens to be issued; inflation rate is too high"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera")));
BOOST_REQUIRE_EQUAL(t.success(), t.setinflation(500, 50000, 40000));
BOOST_REQUIRE_EQUAL(t.wasm_assert_msg("quantity exceeds available supply"), t.push_action(N(defproducera), N(claimrewards), mvo()("owner", "defproducera")));
} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(multiple_producer_pay, eosio_system_tester, * boost::unit_test::tolerance(1e-10)) try {

Expand Down

0 comments on commit 9cc4dcd

Please sign in to comment.