Finding out how does HBD interest work by reviewing code


I mentioned in yesterday's post, you now earn interest (currently 3%) on HBD & HBD savings.

There hasn't been any interest for HBD since I have joined, so I'm going to dive deep into how it works and what you need to know about it by reviewing the code associated with it.

Hived is the software behind Hive nodes and is what is responsible for calculating and distributing interest.

You can find the Github repo here.

Our goal is to answer a few questions to get a better understanding of how HBD interest works.

Some questions off the top of my head

  • Do you earn interest on just savings or both liquid and savings?
  • Can you buy a lot of HBD before interest payout?
  • How often is interest paid out?
  • Do I have to claim interest like rewards?
  • What if you don't do any HBD transactions in 30 days?

There are likely other questions, but let's focus on these for now.

These are great questions and are easily answered by looking at the code. I did a search for interest and looked for the portion of the code that handled paying out interest. It was pretty easy to find and answers our question well.

In the libraries/chain/database.cpp file we can see there is a section of code that does pretty much the same thing twice, once for HBD and once for HBD Savings. It is clear the interest is paid out on both.

Let's review the code presented above and see if we can't figure it out.

          if( acnt.hbd_seconds > 0 &&
              (acnt.hbd_seconds_last_update - acnt.hbd_last_interest_payment).to_seconds() > HIVE_HBD_INTEREST_COMPOUND_INTERVAL_SEC )
            auto interest = acnt.hbd_seconds / HIVE_SECONDS_PER_YEAR;
            interest *= get_dynamic_global_properties().get_hbd_interest_rate();
            interest /= HIVE_100_PERCENT;
            asset interest_paid(interest.to_uint64(), HBD_SYMBOL);
            acnt.hbd_balance += interest_paid;
            acnt.hbd_seconds = 0;
            acnt.hbd_last_interest_payment = head_block_time();

            if(interest > 0)
              push_virtual_operation( interest_operation(, interest_paid ) );

            modify( get_dynamic_global_properties(), [&]( dynamic_global_property_object& props)
              props.current_hbd_supply += interest_paid;
              props.virtual_supply += interest_paid * get_feed_history().current_median_history;
            } );

I'm not going to get too deep here, but I will quickly run through what's happening.

The code first sees if the account has a value greater than 0 in the account's hbd_seconds. If there is, it further checks if the hbd_seconds_last_update is greater than HIVE_HBD_INTEREST_COMPOUND_INTERVAL_SEC.

HIVE_HBD_INTEREST_COMPOUND_INTERVAL_SEC is a constant, this means it is not expected to change throughout the code and why it is in capitals. Let's find this constant in the code and this will answer another one of our questions.

In libraries/protocol/include/hive/protocol/config.hpp we can see HIVE_HBD_INTEREST_COMPOUND_INTERVAL_SEC is defined to 60*60*24*30. As this variable represents seconds, we can see we are multiplying by 60 to get minutes, then by 60 to get hours, then by 24 to get days, then finally 30 to get a total of 30 days worth of seconds.

The first statement requires both criteria to be true to continue. In other words, there has to be more than 0 hbd_seconds on the account and there hasn't been an HBD update in 30 days.

This logic is commonly referred to as a gate, if these two criteria are not met, no further progress in the code is made.

The next section divides the hbd_seconds by another constant that represents how many seconds in a year. At this point we don't know what hbd_seconds represents. Let's try to figure this out.

This portion of the code gives us a good understanding of what hbd_seconds represents. It is a little difficult to understand, but on line 5215 we can see hbd_seconds gets added to hbd_seconds + hbd balance * how many seconds since the last block update. This might be a little confusing, so I will use an example.

Let's say you have 100 HBD. The last update to your HBD balance was 1 hour ago. You now make another HBD transaction which forces an update to your hbd_seconds field.

Let's say you hbd_seconds is 0 to make things simple.

The code above will take your current hbd_seconds (0) and add to the result of 100 (your hbd balance) * seconds since your last update.

You can think of this as a timer that keeps track of how much HBD you own and how long you held. If you held 100 HBD for 29 days, then added 1000 HBD on day 29, your hbd_seconds would largely represent holding 100 HBD for 29 days. When it is time to pay interest on day 30, you would be paid interest on 100 HBD for 29 days and 1100 HBD for something around 1 day.

This means buying and selling right before an interest payout has little affect on your interest. We can also deduce that inactive accounts still are earning interest even if they do not do a HBD transaction within the 30 days, the interest will be paid since the last update once a transaction triggers an interest payout.

Continuing on from the main code, we take the interest variable, which represents the fraction of seconds of the year since your last interest, and multiply it by the current hbd interest rate set by witnesses.

This is then turned into a percentage and then an asset object. This asset (an object that represents a Hive currency) is added to your hbd balance. Your hbd_seconds counter is reset to 0 and the hbd_last_update time is stamped with the current head block timestamp.

Another gate is defined (also called conditional) to check if you are due any interest. If so, a virtual operation is created to payout the interest and broadcast it to the blockchain.

The code finally updates the blockchain hbd_supply and virtual supply counters.

Let's review our questions.

Do you earn interest on just savings or both?

As we discussed, interest is paid out on both.

Can you buy a lot of HBD before interest payout?

Because both the balance and time held is tracked, you cannot buy HBD before interest payouts and sell it after to game the system.

How often is interest paid out?

We can see in the code it is set to 30 days, but this can be easily changed with a hard fork.

Do I have to claim interest like rewards?

As you can see from the code, it is done automatically, what may not have been clear is this is handled whenever you transact with HBD. If you do not do any HBD transactions your interest will continue to build up and payout when a transaction is made.

What if you don't do any HBD transactions in 30 days?

All interest owed will be paid out when an HBD transaction is made. If it is longer than 30 days, you will receive your fair share based on the total time since the last payout.

You can look at to find out the current interest rate by looking in the right hand side. Peakd and Condenser will likely be updated soon to reflect the current interest rate on the wallet page.

You can review your hbd balance and interest fields for your account on as well.

I should receive an hbd interest in roughly 10 days.

If you have any other questions about HBD interest, feel free to drop it in the comment section. Hopefully this helped you understand this change and gave you a little insight in the process.