Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Introducing dynamic computation of bprate #40

Open
wants to merge 1 commit into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ option(SYSTEM_CONFIGURABLE_WASM_LIMITS
option(SYSTEM_BLOCKCHAIN_PARAMETERS
"Enables use of the host functions activated by the BLOCKCHAIN_PARAMETERS protocol feature" ON)

option(BUILD_TESTS "Build unit tests" OFF)


ExternalProject_Add(
contracts_project
SOURCE_DIR ${CMAKE_SOURCE_DIR}/contracts
Expand All @@ -33,12 +36,14 @@ ExternalProject_Add(
-DCMAKE_TOOLCHAIN_FILE=${CDT_ROOT}/lib/cmake/cdt/CDTWasmToolchain.cmake
-DSYSTEM_CONFIGURABLE_WASM_LIMITS=${SYSTEM_CONFIGURABLE_WASM_LIMITS}
-DSYSTEM_BLOCKCHAIN_PARAMETERS=${SYSTEM_BLOCKCHAIN_PARAMETERS}
-DBUILD_TESTS=${BUILD_TESTS}
UPDATE_COMMAND ""
PATCH_COMMAND ""
TEST_COMMAND ""
INSTALL_COMMAND ""
BUILD_ALWAYS 1)


if(APPLE)
set(OPENSSL_ROOT "/usr/local/opt/openssl")
elseif(UNIX)
Expand All @@ -53,7 +58,6 @@ elseif(UNIX)
endif()
set(SECP256K1_ROOT "/usr/local")

option(BUILD_TESTS "Build unit tests" OFF)

if(BUILD_TESTS)
message(STATUS "Building unit tests.")
Expand Down
14 changes: 14 additions & 0 deletions TELOS.README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,14 @@ Down below an accounting off all changes:
### `.github/workflows/ubuntu-2004.yml`
- Changed contract development docker image, and run commands to use my version.

### `contracts/eosio.system/include/eosio.system/bpay_rate.hpp`
- Add file `bpay_rate.hpp`
- Header with function to compute the bpay rate
-
### `contracts/eosio.system/include/eosio.system/delphioracle.hpp`
- Add file `delphioracle.hpp`
- Communicate with delphioracle contract to be able to fetch the averages information

### `contracts/eosio.system/include/eosio.system/eosio.system.hpp`
- Include cmath header
- Add `producer_location_pair` type
Expand All @@ -33,6 +41,8 @@ Down below an accounting off all changes:
- Add `exrsrv,tf`, `telos.decide`, `works.decide` & `amend.decide` account names as constants
- Add `unregreason`, `votebpout`, `setpayrates` & `distviarex` action declarations
- Add auxiliary declarations for claimrewards, voting calculations and scheduling
- Add `bpayrate` action used for testing purposes (only included when building the tests)
- Add `get_last_30_days_tlosusd_average` to fetch from `delphioracle` the last 30 days average for `tlosusd`

### `contracts/eosio.system/include/eosio.system/native.hpp`
- Add `producer_metric` struct
Expand All @@ -55,6 +65,9 @@ Down below an accounting off all changes:
- Call `claimrewards_snapshot` once per day
- Hook our custom producer payment machinery in `claimrewards` action implementation
- Add `claimrewards_snapshot` implementation
- Edit `bpay_rate` computation, instead of using the global `bpay_rate` it computes it based on the supply and last 30 average
- Add `bpayrate` action used for testing purposes (only included when building the tests)
- Add `get_last_30_days_tlosusd_average` to fetch from `delphioracle` the last 30 days average for `tlosusd`

### `contracts/eosio.system/src/rex.cpp`
- Remove voting requirements for staking
Expand Down Expand Up @@ -102,6 +115,7 @@ Down below an accounting off all changes:

### `tests/telos.system_tests.cpp`
- Add custom `producer_onblock_check`, `producer_pay`, `multi_producer_pay`
- Add test for `bpay_rate` to check against the spreadsheet.

### `tests/test_contracts/old_versions/telos.contracts/eosio.msig/README.txt`
- Add old msig contract with readme indicating commit and cdt used to compile
Expand Down
2 changes: 2 additions & 0 deletions contracts/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ option(SYSTEM_CONFIGURABLE_WASM_LIMITS
option(SYSTEM_BLOCKCHAIN_PARAMETERS
"Enables use of the host functions activated by the BLOCKCHAIN_PARAMETERS protocol feature" ON)

option(BUILD_TESTS "Build unit tests" OFF)

find_package(cdt)

set(CDT_VERSION_MIN "3.0")
Expand Down
5 changes: 5 additions & 0 deletions contracts/eosio.system/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ add_contract(
${CMAKE_CURRENT_SOURCE_DIR}/src/name_bidding.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/native.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/producer_pay.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/bpay_rate.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/powerup.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/rex.cpp
${CMAKE_CURRENT_SOURCE_DIR}/src/voting.cpp
Expand All @@ -21,6 +22,10 @@ if(SYSTEM_BLOCKCHAIN_PARAMETERS)
target_compile_definitions(eosio.system PUBLIC SYSTEM_BLOCKCHAIN_PARAMETERS)
endif()

if(BUILD_TESTS)
target_compile_definitions(eosio.system PUBLIC BUILD_TESTS=ON)
endif()

target_include_directories(eosio.system PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_SOURCE_DIR}/../eosio.token/include)

Expand Down
7 changes: 7 additions & 0 deletions contracts/eosio.system/include/eosio.system/bpay_rate.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// TELOS BEGIN
#include <eosio/asset.hpp>

namespace eosiosystem {
double compute_bpay_rate(uint64_t tlos_price, eosio::asset total_telos_supply);
}
// TELOS END
68 changes: 68 additions & 0 deletions contracts/eosio.system/include/eosio.system/delphioracle.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// TELOS BEGIN
#include <eosio/eosio.hpp>
#include <math.h>

using eosio::time_point;
using eosio::const_mem_fun;
using eosio::indexed_by;

namespace delphioracle {

const eosio::time_point NULL_TIME_POINT = eosio::time_point(eosio::microseconds(0));


enum class average_types: uint8_t {
last_7_days = 0,
last_14_days = 1,
last_30_days = 2,
last_45_days = 3,
none = 255,
};

TABLE daily_datapoints {
uint64_t id;
uint64_t value;
time_point timestamp;

uint64_t primary_key() const {
return id;
}
uint64_t by_timestamp() const {
return timestamp.elapsed.to_seconds();
}
uint64_t by_value() const {
return value;
}
};

TABLE averages {
uint64_t id;
uint8_t type = get_type(average_types::none);
uint64_t value = 0;
time_point timestamp = NULL_TIME_POINT;
uint64_t primary_key() const {
return id;
}
uint64_t by_timestamp() const {
return timestamp.elapsed.to_seconds();
}

static uint8_t get_type(average_types type) {
return static_cast < uint8_t > (type);
}
};

typedef eosio::multi_index<
"dailydatapnt"_n,
daily_datapoints,
indexed_by<"value"_n, const_mem_fun<daily_datapoints, uint64_t, &daily_datapoints::by_value>>,
indexed_by<"timestamp"_n, const_mem_fun<daily_datapoints,uint64_t, &daily_datapoints::by_timestamp>>
> dailydatapointstable;

typedef eosio::multi_index<
"averages"_n,
averages,indexed_by <"timestamp"_n, const_mem_fun<averages, uint64_t, &averages::by_timestamp>>
> averagestable;

}
// TELOS END
8 changes: 8 additions & 0 deletions contracts/eosio.system/include/eosio.system/eosio.system.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -1618,6 +1618,13 @@ namespace eosiosystem {
void distviarex(name from, asset amount);


#ifdef BUILD_TESTS
// Defined in producer_pay.cpp
[[eosio::action]]
void bpayrate(uint64_t tlos_price, asset total_telos_supply);
#endif


using unregreason_action = eosio::action_wrapper<"unregreason"_n, &system_contract::unregreason>;
using votebpout_action = eosio::action_wrapper<"votebpout"_n, &system_contract::votebpout>;
using setpayrates_action = eosio::action_wrapper<"setpayrates"_n, &system_contract::setpayrates>;
Expand Down Expand Up @@ -1737,6 +1744,7 @@ namespace eosiosystem {
// TELOS BEGIN
// defined in producer_pay.cpp
void claimrewards_snapshot();
uint64_t get_last_30_days_tlosusd_average();


double inverse_vote_weight(double staked, double amountVotedProducers);
Expand Down
32 changes: 32 additions & 0 deletions contracts/eosio.system/src/bpay_rate.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// TELOS BEGIN
#include <eosio.system/bpay_rate.hpp>

using eosio::asset;

namespace eosiosystem {
double compute_bpay_rate(uint64_t tlos_price, asset total_telos_supply) {
const double MULTIPLIER_CONSTANT = 8.34;
const double POWER_OF_CONSTANT = -0.516;
const double ACTIVE_BP_COUNT = 21;
const double STANDBY_BP_COUNT = 21;

// 100k divided by (30-minutes divided by the Number-of-minutes-in-a-year)
// 100k / 0.00005707762557
// This was pulled out of the bpay_rate formula
const double _100K_DIVIDED_BY_TIME_PERIOD = 1752000000;

const double raw_tlos_price = double(tlos_price) / 100;
const double tlos_per_bp = MULTIPLIER_CONSTANT * pow((double) raw_tlos_price, POWER_OF_CONSTANT);
const double tlos_in_30_mins = tlos_per_bp * (ACTIVE_BP_COUNT + 0.5 * STANDBY_BP_COUNT);

double total_telos_supply_double = double(total_telos_supply.amount) / pow(10.0, total_telos_supply.symbol.precision());

const double bp_rate = round(
(_100K_DIVIDED_BY_TIME_PERIOD* tlos_in_30_mins) /
total_telos_supply_double
);

return bp_rate;
}
}
// TELOS END
31 changes: 30 additions & 1 deletion contracts/eosio.system/src/producer_pay.cpp
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
#include <eosio.system/eosio.system.hpp>
#include <eosio.token/eosio.token.hpp>
// TELOS BEGIN
#include <eosio.system/delphioracle.hpp>
#include "system_kick.cpp"
#include <eosio.system/bpay_rate.hpp>
#define MAX_PRODUCERS 42 // revised for TEDP 2 Phase 2, also set in system_rotation.cpp, change in both places
// TELOS END

Expand Down Expand Up @@ -257,7 +259,9 @@ namespace eosiosystem {

if (usecs_since_last_fill > 0 && _gstate.last_pervote_bucket_fill > time_point())
{
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.
// TELOS BEGIN
double bpay_rate = compute_bpay_rate(get_last_30_days_tlosusd_average(), token_supply);
// TELOS END
auto to_workers = static_cast<int64_t>((12 * double(_gpayrate.worker_amount) * double(usecs_since_last_fill)) / double(useconds_per_year));
auto to_producers = static_cast<int64_t>((bpay_rate * double(token_supply.amount) * double(usecs_since_last_fill)) / double(useconds_per_year));
auto new_tokens = to_workers + to_producers;
Expand Down Expand Up @@ -360,4 +364,29 @@ namespace eosiosystem {
}
}

// TELOS BEGIN
uint64_t system_contract::get_last_30_days_tlosusd_average() {
name delphioracle("delphioracle");
name tlosusd("tlosusd");

delphioracle::averagestable averages(delphioracle, tlosusd.value);
for (auto itr = averages.begin(); itr != averages.end(); ++itr) {
if (itr->type == delphioracle::averages::get_type(delphioracle::average_types::last_30_days)) {
return itr->value;
}
}

check(false, "Last 30 day average not found");
// Silence warning
return 0;
}

#ifdef BUILD_TESTS
void system_contract::bpayrate(uint64_t tlos_price, asset total_telos_supply) {
require_auth(get_self());
check(false, compute_bpay_rate(tlos_price, total_telos_supply));
}
#endif
// TELOS END

} //namespace eosiosystem
53 changes: 53 additions & 0 deletions tests/telos.system_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,4 +403,57 @@ BOOST_FIXTURE_TEST_CASE( ibc_new_account, eosio_system_tester ) try {

} FC_LOG_AND_RETHROW()

BOOST_FIXTURE_TEST_CASE(bpay_rate , eosio_system_tester ) try {

asset TLOS_TOTAL_SUPPLY = core_sym::from_string("420000000.0000");

auto bpay_rate = [&](uint64_t tlos_price, asset tlos_supply) {
return push_action(
config::system_account_name,
"bpayrate"_n,
mvo()("tlos_price", tlos_price)("total_telos_supply", tlos_supply)
);
};

BOOST_REQUIRE_EQUAL(
wasm_assert_code(8250),
bpay_rate(2, TLOS_TOTAL_SUPPLY)
);

BOOST_REQUIRE_EQUAL(
wasm_assert_code(1096),
bpay_rate(100, TLOS_TOTAL_SUPPLY)
);

BOOST_REQUIRE_EQUAL(
wasm_assert_code(1096),
bpay_rate(100, TLOS_TOTAL_SUPPLY)
);

BOOST_REQUIRE_EQUAL(
wasm_assert_code(766),
bpay_rate(200, TLOS_TOTAL_SUPPLY)
);


BOOST_REQUIRE_EQUAL(
wasm_assert_code(478),
bpay_rate(500, TLOS_TOTAL_SUPPLY)
);

BOOST_REQUIRE_EQUAL(
wasm_assert_code(334),
bpay_rate(1000, TLOS_TOTAL_SUPPLY)
);
BOOST_REQUIRE_EQUAL(
wasm_assert_code(146),
bpay_rate(5000, TLOS_TOTAL_SUPPLY)
);

BOOST_REQUIRE_EQUAL(
wasm_assert_code(102),
bpay_rate(10000, TLOS_TOTAL_SUPPLY)
);
} FC_LOG_AND_RETHROW()

BOOST_AUTO_TEST_SUITE_END()
Loading