Skip to content

EOS System Contracts v3.4.0 Release Notes

Latest
Compare
Choose a tag to compare
@nsjames nsjames released this 27 May 23:53
· 8 commits to release/3.4 since this release
fcb2fc4

This release focuses on tokenomic changes.

Overview

Following a discussion around a tokenomics proposal this release introduces changes required to support a significant update in EOS tokenomics that changes the way EOS inflation and distribution function. These system smart contract changes are required to create an onchain multi-sig that block producers will vote on to approve or oppose the proposal.

Token Changes

The proposal centers around a lowering of the maximum supply to 2.1b tokens, and an issuing up to that target number instead of a slow inflation in order to create a fixed supply.

New actions on the eosio.token contract are required to make that possible, as well as some core changes to the way that block producers are paid when the token's maximum supply equals the current supply.

View Token Changes PR

setmaxsupply

void setmaxsupply( 
    const name& issuer, 
    const asset& maximum_supply 
);

Sets the maximum supply of the token to maximum_supply.
The issuer must match the original issuer of the token.

issuefixed

void issuefixed( 
    const name& to, 
    const asset& supply, 
    const string& memo 
);

Issues the delta between the current supply and the supply parameter, and allocates those tokens to the to account.

A memo can also be included.

Changes to block producer rewards and eosio.saving

When a block producer calls claimrewards it will now check if the current supply is equal to
the maximum supply, and if so then it will use the tokens that the eosio account holds.

If not, then it will continue to inflate as it did prior to these changes.

New static methods

To make it easy for external parties to integrate with these changes, and to keep the contract clean internally two new static methods were introduced.

static asset get_max_supply( 
    const name& token_contract_account, 
    const symbol_code& sym_code 
);

static name get_issuer( 
    const name& token_contract_account, 
    const symbol_code& sym_code 
);

Vesting Schedules

In order to distribute the fixed tokens to the relevant parties a vesting schedule is introduced. This allows dynamically setting date/rate pairs that define how much of the existing supply is distributed to block producers and the eosio.saving contract.

View Vesting Schedules PR

schedules table

struct schedules_info {
  time_point_sec   start_time;
  double           continuous_rate;

  uint64_t primary_key() const { return start_time.sec_since_epoch(); }
};

The schedules table holds the time/rate pairs, and is always scoped to self (eosio).

setschedule

void setschedule( 
    const time_point_sec start_time, 
    double continuous_rate 
);

Adds or updates a scheduled vesting distribution rate at a given date to the schedules table.

  • start_time - The date this rate can be applied
  • continuous_rate - A percentage of the current supply divided by 100

An example of a 5% distribution rate:

{"start_time": "2024-06-01T00:00:00Z", "continuous_rate": 0.05}

delschedule

void delschedule( 
    const time_point_sec start_time 
);

Deletes a schedule if it exists, or fails.

execschedule

void execschedule();

Executes the next schedule sorted by closest date. The schedule's start_time must have already passed.

setpayfactor

void setpayfactor( 
    int64_t inflation_pay_factor, 
    int64_t votepay_factor 
);

This new action is identical to the setinflation action except that it does not allow changing the annual_rate which would then compute the continuous_rate, as that is now set through vesting schedules.

This allows modifying the block producer bpay, vpay, and eosio.saving splits.

For more information about how these parameters work, see the comments on the code here.

unvest

void unvest(
    const name account, 
    const asset unvest_net_quantity, 
    const asset unvest_cpu_quantity
);

This action retires the unvested tokens from the b1 account, enforces only the unvested tokens can be touched, and updates the locking logic to allow b1 to take any remaining tokens that have already vested after the unvested tokens have been retired.

Fees Upgrade

In order to allow distribution of system fees to new buckets (block producers, rex, and RAM) and pushing fees from new origins, changes to the system contracts have been made and a new eosio.fees contract will be deployed.

View Fees Upgrade PR

System contract changes and new actions

donatetorex

void donatetorex( 
    const name& payer, 
    const asset& quantity, 
    const std::string& memo 
);

This allows anyone to donate EOS into the REX markets. Since a new eosio.fees contract will be controlling the distribution of fees the system contract needs a way to accept donations from external entities as previously it was only possible internally.

Important to note that this does not require a token transfer, and instead EOS will be taken from the account the same way as the system does in other actions like buyram.

buyramburn

struct action_return_buyram {
  name payer;
  name receiver;
  asset quantity;
  int64_t bytes_purchased;
  int64_t ram_bytes;
  asset fee;
};

action_return_buyram buyramburn( 
    const name& payer, 
    const asset& quantity, 
    const std::string& memo 
);

This action buys ram and burns it within a single action instead of having to call multiple actions.

logsystemfee

void logsystemfee( 
    const name& protocol, 
    const asset& fee, 
    const std::string& memo 
);

The logsystemfee adds another log to the system contracts that helps track fees, where they are coming from and where they are going. It is called inline in every action that would incur fees (such as name auctions, or ram market trades).

Changes to return values and logs

Both logbuyram and logsellram now have a const binary_extension<asset>& fee at the end of their parameter lists. This helps track that fee for external parties.

The action_return_buyram and action_return_sellram return value structs have also been modified to add an asset fee;

Static methods

New methods are exposed on eosio.system.hpp to exposed if REX is available or not. These are aimed at helping integrators that want to use the new donatetorex action.

static bool rex_system_initialized(
    name system_account = "eosio"_n
);

static bool rex_available(
    name system_account = "eosio"_n
);

The get_core_symbol method was also modified to make it simpler to use.

static symbol get_core_symbol( 
    name system_account = "eosio"_n 
);

eosio.fees contract

This new contract handles the distribution of fees to configurable destinations and rates.

This simplifies the ability to control the flow of fees within EOS as well as making them easier to track and view on explorers and other tooling.

Tables

struct strategies_row {
    name       strategy;
    uint16_t   weight;

    uint64_t primary_key() const { return strategy.value; }
};

The strategies table is always scoped to self (eosio).

struct settings_row {
    uint32_t            epoch_time_interval = 600;
    time_point_sec      next_epoch_timestamp;
};

The settings table is always scoped to self (eosio).

init

void init( 
    const uint32_t epoch_time_interval 
);

Initializes the eosio.fees contract and sets the interval allowed for distributions (in seconds).

setstrategy

Available strategies:

  • buyramburn - Buys ram and burns it
  • buyramself - Buy ram for eosio.fees and holds it
  • donatetorex - Sends fees to REX
  • eosio.bpay - Sends fees to be paid to producers
void setstrategy( 
    const name strategy, 
    const uint16_t weight 
)

Sets (create or update) a strategy's weight into effect for subsequent distributions.

  • strategy - Must be one of the predefined strategies above
  • weight - A number proportional to the total weight of all strategies

delstrategy

void delstrategy( const name strategy );

Removes a strategy from distributions.

distribute

void distribute();

Distributes accumulated fees to the designated strategies based on their weights once every epoch period. The next epoch is updated to be a distance of epoch_time_interval from the second this action is called.

Static methods

static uint16_t get_total_weight( 
    const name contract = "eosio.fees"_n 
);

The get_total_weight static method returns the sum of all weights for all configured strategies.

WASM Hashes

eosio.system - b78e2bfcceea88b337f195bb1e362a33cb5365aaaf02a2c32bcbf6698b1b832f
eosio.token - 0a16e1dac533c4558698c8754f41219839ba2a2b75e517e65ea2537f76681f49

Contributors

Special thanks to the contributors that worked on this release:

Full Changelog: v3.3.0...v3.4.0