Node Operator vs Liquidity Provider Yield
We compare the Annualised Percentage Yield (APY) for Thorchain for pools and node operators on aggreagate. We find a steady yield between 35-50% for pools and 15-20% for the bonds of node operators, except for recent weeks, when bond rewards kept rising in an exponential fashion.
Methodology
APY or Annualized Percentage Yield each week for either Node Operator or Liquidity Provider is the amount they would gain yearly given a weeks income divided by their capital investment in percentage terms.
Calculating APY on a given week for the pools is straightforward: divide the weekly rewards of all pools (block_rewards.liquidity_earnings) by the weekly sum of their liquidity. There is one catch though: You need to average the liquidity weekly, by pool before summing, otherwise you'll vastly overestimate the APY denominator.
Calculating the APY for bonds is similar for the nominator; we can sum up the weekly rewards the same way(block_rewards.bonding_earnings). Getting the denominator, the average bonded amount during a week is a bit more tricky, as we don't have a ready to use table for the balances. So we'll construct one using the bond_events table. Steps for doing so:
-
Reformat bonds_events table to assign a
- + bonded_amount_change to the 'bond_paid' and 'bond_reward' events and a - bonded_amount_change to the 'bond_returned' and 'bond_cost' events
- accredit the as bonder_address
- the from_address for a 'bond_cost' event,
- the first string after the ':' in the memo for 'bond_paid' and 'bond_returned' events
split(memo,':')[1]::string
- the to_address for a 'bond_reward' event
-
Calculate the cumulative sum for all accounts as bond_balance (in table balance_007)
Now, for every week we'll need to calculate the total bonded amount for the week for all accounts, as well as only active accounts. To figure out which accounts are active we'll:
- for every node address we'll add a 'standby' current_status at date 2000-01-01 to make sure every account is initially off. As Ripley said it's the only way to be sure. (table status_007)
- left join balance_007 to status_007 on balance_007.bonder_address = status_007.node_address keeping row where status_time < balance_time, and group_by balance_time and bonder_address to get the last value of the node_status (table balanced_status_007)
- Last, but not least sum the weekly average of accounts in balanced_status_007,
- either as is to get the total_bonded_amount for all nodes or
- filtering for last_status = 'active' to get the active_bonded_amount
...and this would even work too, except for the fact, that the bond_events table do not contain an entry for all bonder addresses each week. To rectify this unfortunate turn of events we project the contents of the balanced_status_007 table to all dates in rewards table by:
- for each registered change in bond_balance we find the time of the next change for the same bonder_address
- cross join the balanced_status_007 x dates and keep dates that are greater or equal than the time of the balance change, but smaller than the time of the next change (project the balances forward)
Thorchains pools had a laudable and steady 50% average APY performance in their first 3 months of operation, reaching as high as 130% before the July shutdown. In the same period bond yields were in the 15-20% range. Following the recovery after the hiatus due to the July hack pool APY settled a bit lower ~35%, reaching 50/60% peaks at the autumn high and January and March of 2022. A marked low in pool APY could be seen in November at the start of the bear market. Bond APYs stayed around 15% until 2022 and saw a first marked increase in the second half of January, and second much larger one starting from April. From the beginning of April bond rewards kept rising up to 80% for active validators last week, signalling an extreme need for Thorchain to draw in bond liquidity and incentives it's validators.