Formulas

Formulas #

Network Staking Ratio #

Staking ratio is a unit-less percentage that expresses how much of the total supply actively participates in consensus-related staking at each block.

The network-wide staking ratio is determined by all actively staking coins (the portion of staking supply that is available to active bakers and thus used for securing consensus) divided by total supply (all coins currently in existence).

staking_ratio = active_staking / total_supply * 100

Current Rewards % #

Rewards is a unit-less percentage that expresses how much annual return each staked tez can generate. Keep in mind that this is only an estimate and not a guarantee. Expected rewards change all the time due to network dynamics and staking ratio. That’s why we call them current rewards instead of future rewards.

The amount of future staking rewards depends on the network staking ratio, but also on the total amount of rewards that are actually generated by the network. Under ideal circumstances, bakers would earn the maximum possible block rewards, but in reality rewards are 8-10% lower than ideal because some bakers fail to produce blocks or endorsements due to different factors. To accommodate for these differences we estimate rewards based on the staking ratio and historic inflation seen during the past year.

inflation_1y = total_supply[now] - total_supply[now - 365 days]
current_rewards = inflation_1y / active_staking * 100

Absolute inflation in tez is calculated by current total supply minus total supply a year ago. For simplicity, the formula neglects the amount of tez which is burned (empirically, burn is only 0.001% of issuance). Current rewards are then estimated by dividing inflation by active staking supply.

Past Inflation % #

The real annual inflation rate is a unit-less percentage that expresses how much the total supply has changed over the past 365 days, either by adding new supply through issuance of block rewards or by removing supply through burning tez.

total_supply_now = total_supply
total_supply_last_year = total_supply[now - 365 days]
inflation_rate_1y = (total_supply_now - total_supply_last_year) / total_supply_last_year

We calculate the inflation rate by taking the difference between the current total supply and last year’s total supply and dividing it by last year’s total supply.

Network Health #

Network Health is a ratio-scale metric in the range of [0.0 .. 100.0] that represents the current stability and security of the Tezos Blockchain. The best possible value of 100 describes flawless operation at maximum consensus security. Health is derived by deducting penalties for negative events such as worse block priorities, lower endorsement rate, and higher orphan rate over the past 128 blocks.

Health is supposed to give an immediate sense of the current state of the network in real time. We dampen the effect of past events by applying a decay factor of 1/n where n is the distance of an event from the most recently seen (or expected) block.

If the next block is overdue, its minimum priority is estimated based on the last seen block timestamp and the expected duration between blocks (i.e. 60/40 sec).

// maximum health is 100
health := 100.0

// penalties
missedPriorityPenalty := 2.0
missedEndorsePenalty  := 0.5
orphanPenalty         := 5.0

// process past 127 blocks in reverse order
for i, b := range recentBlocks {
	// assign block weight
	weight := 1.0 / float64(recentBlocks[0].Height - b.Height + 1)

	if b.IsOrphan {
		// penalize reorgs
		health -= orphanPenalty * weight
	} else {
		// penalize missed priorities
		health -= float64(b.Priority) * missedPriorityPenalty * weight

		// penalize missed endorsement slots (Note the latest block is not yet endorsed)
		if i > 0 {
			missed := params.EndorsersPerBlock - b.NSlotsEndorsed
			health -= missed * missedEndorsePenalty * weight
		}
	}
}

// final block gets penalty when overdue
delay := time.Now() - recentBlocks[0].Timestamp
t1 := params.TimeBetweenBlocks[0]
t2 := params.TimeBetweenBlocks[1]

if delay > t1 {
	estimatedPriority := (delay - t1 + t2 / 2) / t2 + 1
	health -= float64(estimatedPriority) * missedPriorityPenalty
}

// normalize
health = math.Round(math.Max(health, 0))

Baker Capacity #

Baker capacity is an estimate for the amount of staking balance a baker can sustain without losing block rewards due to a shortage of bonds. Capacity helps bakers and delegators to plan ahead and avoid overdelegation.

As bakers receive future rights to bake and endorse blocks in direct relation to their staking balance (own + delegated tez) and they have to pay down a security deposit to bake and endorse blocks, the amount of available funds for bonds should always remain above deposit requirements.

In case baker funds are depleted (i.e. all funds are locked up as security deposit) a baker cannot produce any further blocks or endorsements. This means the baker will forfeit rewards on those opportunities, delegators will receive fewer payouts than expected and other bakers will be impacted too because they suffer from low priority blocks and missing endorsements which directly impacts their rewards as well.

// constants
preserved_cycles = 5
block_security_deposit = 512
endorsement_security_deposit = 64
endorsers_per_block = 32
blocks_per_cycle = 4096
tokens_per_roll = 8000

// variables
network_rolls = X // current sum of rolls across all bakers (`tip.rolls`)
baker_balance = Z // baker own total balance (`account.total_balance`)
                  // sum of spendable, frozen deposits, frozen fees, but NOT frozen rewards

// formulas
block_deposits = block_security_deposit + endorsement_security_deposit * endorsers_per_block
network_bond = block_deposits * blocks_per_cycle * (preserved_cycles + 1)
network_stake = network_rolls * tokens_per_roll
baker_capacity = (baker_balance / network_bond) * network_stake

Our calculation is based on network constants and direct measurement of network-wide rolls. We then estimate which share of the network-wide bond pool a baker currently owns and use this to determine how much of the current network stake the baker could support based on its own available balance.

The formula is simple and correct on average but does not account for randomness or real-world events. For example, it ignores luck (a baker receives an over-proportional amount of rights), the impact of 3rd party overdelegation (baking low priority blocks also require deposits), and dynamic effects introduced by shifts in network stake.

For example, if a baker would receive more delegations up to its currently reported capacity this would probably change network-wide rolls which in turn would change the estimated capacity.

Baker Luck #

Luck expresses actual rights assigned vs. fair-share rights based on rolls. Good luck is when a baker received more rights in a cycle than their fair share. Bad luck is the opposite. Neutral luck is anchored at 100% meaning an exact match between rolls and assigned rights. Other websites may use different anchor points when reporting luck.

// fraction of all rolls
rollsShare := float64(baker.Rolls) / float64(totalRolls)

// full blocks, truncated
fairBakingShare := int64(math.Round(rollsShare * 4096))

// full endorsements, truncated
fairEndorsingShare := int64(math.Round(rollsShare * 4096 * 32))

// best-case fair income as a multiple of blocks and endorsements
fairIncome := fairBakingShare * 40
fairIncome += fairEndorsingShare * 1.25

// luck == diff between expected and fair income (positive when higher, negative when lower)
baker.Luck = baker.ExpectedIncome - fairIncome

// absolute luck as expected vs fair income where 100% is the ideal case
// =100%: fair == expected (luck == 0)
// <100%: fair > expected (luck < 0)
// >100%: fair < expected (luck > 0)
if fairIncome > 0 {
	baker.LuckPct = 10000 + baker.Luck*10000/fairIncome
}

Baker Performance #

There are 2 types of baker efficiency metrics that we measure on TzStats. The first is performance measured in monetary terms, which tells how much tez a baker actually earned in relation to how much could be earned under optimal conditions. The second is reliability measured in technical terms, telling how many of the reward opportunities to bake/endorse a baker successfully completed.

Performance can be lower than 100% when

  1. a baker fails to produce an assigned block or endorsement on time (due to outage)
  2. a baker fails to produce an assigned block or endorsement due to lack of bonds (a.k.a. overdelegation)
  3. a baked block does not contain all endorsements (due to other bakers failing to send them or network propagation issues)
  4. when endorsed blocks have a priority other than zero (due to the first block baker failing to create that block).

Performance can be higher than 100% when

  1. a baker rescues a block and bakes it at a higher priority
  2. a baker publishes own or others seed nonces

With the Carthage network upgrade, rewards have become more dynamic in response to missing endorsements or blocks. There are also some bakers who are notoriously overdelegated. That’s why most bakers don’t reach 100% performance. It’s also the reason why inflation is about 8% below target at the moment.

Performance is calculated via the following code. Updates on the currently active cycle happen each block.

// best-case expected income is based on assigned baking and endorsing rights
baker.ExpectedIncome = 40 * baker.NBakingRights + 1.25 * baker.NEndorsingRights

// total income is based on actual performance
totalGain := baker.TotalIncome - baker.TotalLost - baker.ExpectedIncome

// don't penalize small bakers without any rights/work in a cycle
if baker.ExpectedIncome > 0 {
	baker.PerformancePct = 10000 + totalGain*10000/baker.ExpectedIncome
} else {
	baker.PerformancePct = 10000
}

We use a similar way to calculate baker reliability as unit-less percentage. Here we look at the number of successfully completed rights vs. all assigned rights in a cycle. Reliability cannot be higher than 100%.

Baker ROI #

Return on Investment is a unit-less percentage that expresses how many rewards were generated over the course of a single cycle in relation to the amount of security deposit locked down for all realized opportunities. As blocks rewards are dynamic, i.e. they depend on other bakers' reliabilities, block priority and number of included endorsements which may be impacted by network propagation, the effective ROI can fluctuate.

Baker ROI is calculated as:

  • past cycles: total income (total sum of all income) divided by total bonds (actual deposits).
  • future cycles: expected income (total income expected based on endorsing and priority 0 baking rights) divided by expected bonds (total expected deposits based on endorsing and priority 0 baking rights).
// future cycles
roi = expected_income / expected_bonds

// past cycles
roi = total_income / total_bonds

Payout Split #

When bakers split earned block rewards and pay them out to delegators we apply the most common formula for calcuating the expected outcome of the split. We assume bakers take their own share (based on own funds held at the baker) first, then deduct their commission rate and then split the remainder across delegators.

With very few exceptions a payout is related to delegation balances at a past snapshot block which was used to derive a certain number of rights for the baker. Once these rights are successfully translated into rewards and the rewards are unfrozen (some bakers pay early), the baker pays them out.

baker_commission = X // fixed value signalled off-chain
effective_income = income[cycle].total_income // summary of on-chain reward events

baker_own_share = snapshot_balance / (snapshot_balance + snapshot_delegated)
baker_own_income = effective_income * baker_own_share;
baker_fee_income = (effective_income - baker_own_income) * baker_commission;
baker_reward = baker_own_income + baker_fee_income;
baker_payout = effective_income - baker_reward;

We use the total cycle income which is a sum of all rewards from blocks, endorsements and seed nonce revelations plus rewards from denunciations. Some bakers may not account for all these events in their payouts.

The baker’s own share is based on the baker’s total balance at snapshot, which famously does not include frozen rewards.

In an attempt to stay fair with delegators our formula does not consider slashing losses to decrease income. We also asssume the baker pays transaction fees for a payout. We also do not consider different commission rates a baker may have privately negotiated with a delegator.