Scorum
founders_initializator.cpp
Go to the documentation of this file.
3 
4 #include <fc/exception/exception.hpp>
5 #include <fc/uint128.hpp>
6 
9 
11 
13 
14 #include <limits>
15 
16 namespace scorum {
17 namespace chain {
18 namespace genesis {
19 
21 {
22  if (!is_founders_pool_exists(ctx))
23  {
24  dlog("There is no founders supply.");
25  return;
26  }
27 
28  FC_ASSERT(SCORUM_100_PERCENT <= std::numeric_limits<uint16_t>::max()); // constant value check
29 
30  FC_ASSERT(ctx.genesis_state().founders_supply.symbol() == SP_SYMBOL);
31 
32  check_founders(ctx);
33 
34  account_name_type pitiful;
35  asset founders_supply_rest = distribure_sp_by_percent(ctx, pitiful);
36  if (founders_supply_rest.amount > (share_value_type)0)
37  {
38  distribure_sp_rest(ctx, founders_supply_rest, pitiful);
39  }
40 }
41 
42 bool founders_initializator_impl::is_founders_pool_exists(initializator_context& ctx)
43 {
44  return ctx.genesis_state().founders_supply.amount.value || !ctx.genesis_state().founders.empty();
45 }
46 
47 void founders_initializator_impl::check_founders(initializator_context& ctx)
48 {
49  account_service_i& account_service = ctx.services().account_service();
50 
51  uint16_t total_sp_percent = 0u;
52  for (auto& founder : ctx.genesis_state().founders)
53  {
54  FC_ASSERT(!founder.name.empty(), "Founder 'name' should not be empty.");
55 
56  account_service.check_account_existence(founder.name);
57 
58  FC_ASSERT(founder.sp_percent >= 0.f && founder.sp_percent <= 100.f,
59  "Founder 'sp_percent' should be in range [0, 100]. ${1} received.", ("1", founder.sp_percent));
60 
61  total_sp_percent += SCORUM_PERCENT(founder.sp_percent);
62 
63  FC_ASSERT(total_sp_percent <= (uint16_t)SCORUM_100_PERCENT, "Total 'sp_percent' more then 100%.");
64  }
65  FC_ASSERT(total_sp_percent > 0u, "Total 'sp_percent' less or equal zerro.");
66 }
67 
68 asset founders_initializator_impl::distribure_sp_by_percent(initializator_context& ctx, account_name_type& pitiful)
69 {
70  asset founders_supply_rest = ctx.genesis_state().founders_supply;
71  for (auto& founder : ctx.genesis_state().founders)
72  {
73  uint16_t percent = SCORUM_PERCENT(founder.sp_percent);
74 
75  asset sp_bonus = ctx.genesis_state().founders_supply * utils::make_fraction(percent, SCORUM_100_PERCENT);
76 
77  if (sp_bonus.amount > (share_value_type)0)
78  {
79  feed_account(ctx, founder.name, sp_bonus);
80  founders_supply_rest -= sp_bonus;
81  }
82  else if (founder.sp_percent > 0.f)
83  {
84  pitiful = founder.name; // only last pitiful is getting SP
85  }
86  }
87  return founders_supply_rest;
88 }
89 
90 void founders_initializator_impl::distribure_sp_rest(initializator_context& ctx,
91  const asset& rest,
92  const account_name_type& pitiful)
93 {
94  static const float sp_percent_limit_for_pitiful = 0.02f;
95 
96  FC_ASSERT(rest < ctx.genesis_state().founders_supply
97  * utils::make_fraction(SCORUM_PERCENT(sp_percent_limit_for_pitiful), SCORUM_100_PERCENT),
98  "Too big rest ${r} for single pitiful. There are many pitiful members in genesis maybe.", ("r", rest));
99 
100  asset founders_supply_rest = rest;
101  if (pitiful != account_name_type())
102  {
103  feed_account(ctx, pitiful, founders_supply_rest);
104  founders_supply_rest.amount = 0;
105  }
106 
107  FC_ASSERT(!founders_supply_rest.amount.value);
108 }
109 
110 void founders_initializator_impl::feed_account(initializator_context& ctx,
111  const account_name_type& name,
112  const asset& sp)
113 {
114  account_service_i& account_service = ctx.services().account_service();
115 
116  const auto& founder_obj = account_service.get_account(name);
117  account_service.increase_scorumpower(founder_obj, sp);
118 }
119 }
120 }
121 }
const genesis_state_type & genesis_state() const
#define SCORUM_PERCENT(X)
Definition: config.hpp:203
#define SP_SYMBOL
Definition: config.hpp:104
#define SCORUM_100_PERCENT
Definition: config.hpp:200
fc::fixed_string_16 account_name_type
Definition: types.hpp:62
int64_t share_value_type
Definition: types.hpp:72
Definition: asset.cpp:15
virtual const account_object & get_account(const account_name_type &) const =0
virtual void check_account_existence(const account_name_type &, const optional< const char * > &context_type_name=optional< const char * >()) const =0
std::vector< founder_type > founders
asset_symbol_type symbol() const
Definition: asset.hpp:32
share_type amount
Definition: asset.hpp:31