exchange-rate-list

Exchange rate list is a component containing exchange rates between 1 unit of target sidechain native currency and pBTC. Exchange rates are used during deposit and withdrawal process, for calculating how much pBTC should be issued for a given amount of sidechain native currency, or how much sidechain native currency should be paid to the user for a given amount of pBTC.

Exchange rate list operations should be implemented in core, not in a plugin. Using exchange rate list operations should not be allowed to all users. E.g. only committee members or Peerplays network administrators may use them. However, handling exchange rates as proposals, and waiting for network members to vote, may not be the best solution, as the circumstances might require that exchange rate becomes active immediately, to prevent network misuse, or pulling funds on unfair conditions (e.g. when currency value variations are too high, or a lot of users start pulling funds out of the network).

Access to functions to add, update or delete exchange rate, should not be allowed to all users on the network, but only to users which are considered Peerplays network adminsitrators, or committee members.

Requirements

  • Exchange rate list contains exchange rates between 1 unit of target sidechain native currency and pBTC.

  • All values are stored as int64_t (or uint_64_t, still to decide), and expressed in minimal currency units (1 BTC = 100000000 Satoshi’s, 1 ETH = 1000000000000000000 wei’s, 1 EOS = 1000 whatever, etc…)

  • Exchange rate can be added, deleted and updated by authorized entity (user or SON network)

  • Exchange rate list can be expanded with timestamp field, showing UTC date and time from when the exchange rate should be used. Version with timestamp is harder to implement and maintain.

  • Exchange rate list operations

    • create_exchange_rate - creates exchange rate

    • update_exchange_rate - updates exchange rate

    • delete_exchange_rate - deletes exchange rate

  • Exchange rate wallet functions

    • create_exchange_rate - creates exchange rate

    • update_exchange_rate - updates exchange rate

    • delete_exchange_rate - deletes exchange rate

    • get_exchange_rate - gets a single exchange rate (by id, or network, or network and timestamp)

    • list_exchange_rates - lists all exchange rates

Examples of exchange rate list

Following table shows simplest exchange rate list with no saved history of exchange rates

Currency

Currency amount

pBTC amount

BTC

100000000

X

EOS

1000

Y

ETH

1000000000000000000

Z

Following table shows exchange rate list, expanded with timestamp field, which is able to save exchange rate history

BTC

2019-11-20 00:00:00

100000000

X

BTC

2019-11-25 00:00:00

100000000

X1

EOS

2019-11-20 10:00:00

1000

Y

EOS

2019-11-24 14:00:00

1000

Y1

ETH

2019-11-21 07:00:00

1000000000000000000

Z

ETH

2019-11-23 00:00:00

1000000000000000000

Z1

Implementation

Consider the following code as a suggestion, not as a 100% completed ad working implementation. Syntax errors may be present.

Following declaration needs to be moved from SON plugin, to the core:

enum networks {

bitcoin,

eos,

ethereum

};

Exchange rate object:

class exchange_rate_object : public graphene::db::abstract_object<exchange_rate_object> {

uint32_t exchange_rate_id; // Primary key

network network; // Network managing the currency

int64_t exchange_from; // Network native currency amount

int64_t exchange_to; // Peerplays asset amount (pBTC)

}

// Version with timestamp

class exchange_rate_object : public graphene::db::abstract_object<exchange_rate_object> {

uint32_t exchange_rate_id; // Primary key

network network; // Network managing the currency

time_point_sec valid_from; // Starting date when exchange rate becomes valid

int64_t exchange_from; // Network native currency amount

int64_t exchange_to; // Peerplays asset amount (pBTC)

}

Exchange rate list index:

struct by_network;

using exchange_rate_multi_index_type = multi_index_container<

exchange_rate_object,

indexed_by<

ordered_unique< tag<by_id>,

member<object, object_id_type, &object::id>

>,

ordered_unique< tag<by_network>,

member<exchange_rate_object, network, &exchange_rate_object::network>

>

>

>;

// Version with timestamp

struct by_network_valid_from;

using exchange_rate_multi_index_type = multi_index_container<

exchange_rate_object,

indexed_by<

ordered_unique< tag<by_id>,

member<object, object_id_type, &object::id>

>,

ordered_unique< tag<by_network_valid_from>,

composite_key<exchange_rate_object,

member<exchange_rate_object, network, &exchange_rate_object::network>,

member<exchange_rate_object, time_point_sec, &exchange_rate_object::valid_from>,

>

>

>

>;

  • Exchange rate list should be indexed at least by network and valid_from fields, so a composite key is required.

  • Exchange rate list will be queried with parameters network and timestamp, and the query should return exchange rate valid at a date and time from the timestamp. Exchange rate is valid from the latest timestamp less than the timestamp parameter. E.g. we have the following exchange rate list:

    BTC, 2019-11-20 00:00:00, 100000000, X BTC, 2019-11-25 00:00:00, 100000000, X1

    If we query the index with (network::bitcoin, 2019-11-23), query should return value X, since that exchange rate is valid in the period of [2019-11-20 00:00:00 to 2019-11-24 23:59:59]

    Read Boost MultiIndex docs, to learn about all the ways this is possible to do: https://www.boost.org/doc/libs/1_67_0/libs/multi_index/doc/tutorial/basics.html#special_lookup

Exchange rate create operations:

struct exchange_rate_create_operation : public base_operation

{

uint32_t exchange_rate_id; // Primary key

network network; // Network managing the currency

int64_t exchange_from; // Network native currency amount

int64_t exchange_to; // Peerplays asset amount (pBTC)

void validate()const;

};

// Version with timestamp

struct exchange_rate_create_operation : public base_operation

{

uint32_t exchange_rate_id; // Primary key

network network; // Network managing the currency

time_point_sec valid_from; // Starting date when exchange rate becomes valid

int64_t exchange_from; // Network native currency amount

int64_t exchange_to; // Peerplays asset amount (pBTC)

void validate()const;

};

Validation should check that the item is not duplicated. Eventually, it can check exchange_from precision, since they are known in advance.

Exchange rate update operations:

struct exchange_rate_update_operation : public base_operation

{

uint32_t exchange_rate_id; // Primary key

network network; // Network managing the currency

int64_t exchange_from; // Network native currency amount

int64_t exchange_to; // Peerplays asset amount (pBTC)

void validate()const;

};

// Version with timestamp

struct exchange_rate_update_operation : public base_operation

{

uint32_t exchange_rate_id; // Primary key

network network; // Network managing the currency

time_point_sec valid_from; // Starting date when exchange rate becomes valid

int64_t exchange_from; // Network native currency amount

int64_t exchange_to; // Peerplays asset amount (pBTC)

void validate()const;

};

Validation should check that the item with the given exchange_rate_id exists in the list.

Exchange rate list delete operation:

// Same for both versions

struct exchange_rate_delete_operation : public base_operation

{

uint32_t exchange_rate_id; // Primary key

void validate()const;

};

Validation should check that the item with the given exchange_rate_id exists in the list.

Appropriate evaluators must be implemented too.