11#include < eosio.system/eosio.system.hpp>
22#include < eosio.token/eosio.token.hpp>
33// TELOS BEGIN
4+ #include < eosio.tedp/eosio.tedp.hpp>
5+ #include < delphioracle/delphioracle.hpp>
46#include " system_kick.cpp"
57#define MAX_PRODUCERS 42 // revised for TEDP 2 Phase 2, also set in system_rotation.cpp, change in both places
68// TELOS END
@@ -242,6 +244,37 @@ namespace eosiosystem {
242244 */
243245 }
244246
247+ // TELOS BEGIN
248+ uint64_t system_contract::get_telos_average_price () {
249+ // Reads the delphi oracle TLOS/USD price
250+ delphioracle::averagestable averages_table (delphi_oracle_account, " tlosusd" _n.value );
251+
252+ // Gets monthly average TLOS price
253+ for (auto itr = averages_table.begin (); itr != averages_table.end (); ++itr) {
254+ if (itr->type == delphioracle::averages::get_type (average_types::last_30_days)) {
255+ return itr->value ;
256+ }
257+ }
258+
259+ // Gets 14 days average if monthly average is not available
260+ for (auto itr = averages_table.begin (); itr != averages_table.end (); ++itr) {
261+ if (itr->type == delphioracle::averages::get_type (average_types::last_14_days)) {
262+ return itr->value ;
263+ }
264+ }
265+
266+ // Gets 7 days average if 14 days average is not available
267+ for (auto itr = averages_table.begin (); itr != averages_table.end (); ++itr) {
268+ if (itr->type == delphioracle::averages::get_type (average_types::last_7_days)) {
269+ return itr->value ;
270+ }
271+ }
272+
273+ // Returns smallest non zero value if no price is available
274+ return 1 ;
275+ }
276+ // TELOS END
277+
245278 void system_contract::claimrewards_snapshot () {
246279 check (_gstate.thresh_activated_stake_time > time_point (), " cannot take snapshot until chain is activated" );
247280
@@ -252,14 +285,16 @@ namespace eosiosystem {
252285
253286 auto ct = current_time_point ();
254287
255- const asset token_supply = eosio::token::get_supply (token_account, core_symbol ().code () );
256288 const auto usecs_since_last_fill = (ct - _gstate.last_pervote_bucket_fill ).count ();
257289
258290 if (usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point ())
259291 {
260- double bpay_rate = double (_gpayrate.bpay_rate ) / double (100000 ); // NOTE: both bpay_rate and divisor were int64s which evaluated to 0. The divisor must be a double to get percentage.
292+ // TELOS BEGIN
293+ uint64_t tlos_price = get_telos_average_price ();
261294 auto to_workers = static_cast <int64_t >((12 * double (_gpayrate.worker_amount ) * double (usecs_since_last_fill)) / double (useconds_per_year));
262- auto to_producers = static_cast <int64_t >((bpay_rate * double (token_supply.amount ) * double (usecs_since_last_fill)) / double (useconds_per_year));
295+ double bp_pay_per_month = std::min ((double (378000 ) * std::pow (tlos_price/10000.0 ,-0.516 )),double (882000 )) * 10000 ;
296+ auto to_producers = static_cast <int64_t >((bp_pay_per_month * 12 * double (usecs_since_last_fill)) / double (useconds_per_year));
297+ // TELOS END
263298 auto new_tokens = to_workers + to_producers;
264299
265300 // NOTE: This line can cause failure if eosio.tedp doesn't have a balance emplacement
@@ -360,4 +395,84 @@ namespace eosiosystem {
360395 }
361396 }
362397
398+ // TELOS BEGIN
399+ void system_contract::pay () {
400+ // Reads the payouts table
401+ tedp::payout_table payouts (tedp_account, tedp_account.value );
402+
403+ // Gets daily median TLOS price
404+ uint64_t tlos_price = get_telos_average_price ();
405+
406+ uint64_t now_ms = current_time_point ().sec_since_epoch ();
407+ bool payouts_made = false ;
408+ int64_t new_tokens = 0 ;
409+
410+ for (auto itr = payouts.begin (); itr != payouts.end (); itr++)
411+ {
412+ auto p = *itr;
413+
414+ uint64_t time_since_last_payout = now_ms - p.last_payout ;
415+
416+ uint64_t payouts_due = time_since_last_payout / p.interval ;
417+
418+ if (payouts_due == 0 )
419+ continue ;
420+
421+ if (p.amount == 0 )
422+ continue ;
423+
424+ uint64_t total_due = (payouts_due * p.amount ) * 10000 ;
425+ payouts_made = true ;
426+
427+ if (p.to == REX_ACCOUNT)
428+ {
429+ uint64_t payout = total_due;
430+ if (tlos_price >= 10000 && tlos_price < 20000 ) { // If TLOS daily close of $1.00, the payout will be decreased to 2/3
431+ payout *= 2 ;
432+ payout /= 3 ;
433+ } else if (tlos_price > 20000 ) { // If TLOS daily close of $2.00, the payout will be decreased to 1/3
434+ payout /= 3 ;
435+ }
436+ new_tokens += payout;
437+ }
438+ else
439+ {
440+ new_tokens += total_due;
441+ }
442+ }
443+
444+ // Check if any payouts are needed to be made
445+ check (payouts_made, " No payouts are due" );
446+
447+ // Gets the TEDP account balance
448+ asset tedp_balance = eosio::token::get_balance (token_account, tedp_account, core_symbol ().code ());
449+
450+ // Calculates the amount of TLOS need to be issued
451+ int64_t issue_tokens = 0 ;
452+ if (tedp_balance.amount > 0 ) {
453+ if (tedp_balance.amount < new_tokens) {
454+ issue_tokens = new_tokens - tedp_balance.amount ;
455+ }
456+ } else {
457+ issue_tokens = new_tokens;
458+ }
459+
460+ // Issues TLOS if the TEDP account doesn't have sufficient balance
461+ if (issue_tokens > 0 ) {
462+ token::transfer_action transfer_act{ token_account, { get_self (), active_permission } };
463+ token::issue_action issue_action{ token_account, { get_self (), active_permission }};
464+ issue_action.send (get_self (), asset (issue_tokens, core_symbol ()), " Issue new TLOS tokens" );
465+ transfer_act.send (get_self (), tedp_account, asset (issue_tokens, core_symbol ()), " Transfer issued TLOS to TEDP account" );
466+ }
467+
468+ // Triggers pay action of TEDP account to distribute payouts
469+ eosio::action (
470+ eosio::permission_level{get_self (),active_permission},
471+ tedp_account,
472+ " pay" _n,
473+ std::make_tuple ()
474+ ).send ();
475+ }
476+ // TELOS END
477+
363478} // namespace eosiosystem
0 commit comments