In a proof of stake blockchain, validators need to split the rewards gained from transaction fees each block. Furthermore, these fees must be fairly distributed to each of a validator's constituent delegators. They accrue this reward throughout the entire time they are delegated, and they have a special operation to withdraw accrued rewards.
The F1 fee distribution scheme works for any algorithm to split funds between validators each block, with minimal iteration, and the only approximations being due to finite decimal precision. Per block there is a single iteration over the validator set, which enables only rewarding validators who signed a given block. No iteration is required to delegate, and withdrawing only requires iterating over all of that validators slashes since delegation it began. State usage is minimal as well, one state update per validator per block, and one state record per delegator.
In a proof of stake blockchain, each validator has an associated stake.
Transaction fees get rewarded to validators based on the incentive scheme of the underlying proof of stake model.
The fee distribution problem occurs in proof of stake blockchains supporting delegation, as there is a need to distribute a validator's fee rewards to its delegators.
The trivial solution of just giving the rewards to each delegator every block is too expensive to perform on-chain.
So instead fee distribution algorithms have delegators perform an explicit withdraw transaction, which when performed yields the same total amount of fees as if they had received them at every block.
This details F1, an approximation-free, slash-tolerant fee distribution algorithm which allows validator commission-rates, inflation rates, and fee proportions, which can all efficiently change per validator, every block.
The algorithm requires iterating over the validators every block, and withdraws require iterating over all of the corresponding validator's slashes whilst the delegator was bonded.
The former iteration is cheap, due to staking logic already requiring iteration over all validators, which causes the expensive state-reads to be cached.
The number of slashes is expected to be 0 or 1 for most validators,
so the latter term also meets the blockchain's efficiency needs.
The key point of how F1 works is that it tracks how much rewards a delegator with 1 stake for a given validator would be entitled to if it had bonded at block 0 until the latest block.
When a delegator bonds at block $b$, the amount of rewards a delegator with 1 stake would have if bonded at block 0 until block $b$ is also persisted to state.
When the delegator withdraws, they receive the difference of these two values.
Since rewards are distributed according to stake-weighting, this amount of rewards can be scaled by the amount of stake a delegator had.
Section 1.2 describes this in more detail, with an argument for it being approximation free.
Section 2 details how to adapt this algorithm to handle commission rates, slashing, and inflation.
\subsection{Base algorithm}
In this section, we show that the F1 base algorithm gives each delegator rewards identical to that which they'd receive in the naive and correct fee distribution algorithm that iterated over all delegators every block.
Even distribution of a validators rewards amongst its validators weighted by stake means the following:
Suppose a delegator delegates $x$ stake to a validator $v$ at block $h$.
It is clear from the equations that this payout mechanism maintains correctness, and requires no iterations. It just needed the two state reads for these entries.
Commission rates are the idea that a validator can take a fixed $x\%$ cut of all of their received fees, before redistributing evenly to the constituent delegators.
This can easily be done as follows:
In block $h$ a validator receives $f_h$ fees.
Instead of incrementing that validators ``total accrued fees this period variable" by $f_h$, it is instead incremented by $(1- commission\_rate)* f_p$.
Then $commission\_rate * f_p$ is deposited directly to the validator's account.
This allows for efficient updates to a validator's commission rate every block if desired.
More generally, each validator could have a function which takes their fees as input, and outputs a set of outputs to pay these fees too. (i.e. x\% going to themselves, y\% to delegators, z\% burnt)
A malicious validator that gets itself slashed many times would increase the gas to withdraw linearly, but the economic loss of funds due to the slashes should far out-weigh the extra overhead the honest withdrawer must pay for due to the gas.
Inflation is the idea that we want every staked coin to create more staking tokens as time progresses.
The purpose being to drive down the relative worth of unstaked tokens.
Each block, every staked token should produce $x$ staking tokens as inflation, where $x$ is calculated from a function $inflation$ which takes state and the block information as input.
Let $x_i$ represent the evaluation of $inflation$ in the $i$th block.
The goal of this section is to auto-bond inflation in the fee distribution model without iteration.
This is done by preserving the invariant that every state entry contains the rewards one would have if they had bonded one stake at genesis until that corresponding block.
In state a variable should be kept for the number of tokens one would have now due to inflation,
given that they bonded one token at genesis.
This is $\prod_{0}^{now}(1+ x_i)$.
Each period now stores this total inflation product along with what it already stores per-period.
Let $R_i$ be the fee rewards in block $i$, and $n_i$ be the total amount bonded to that validator in that block.
The correct amount of rewards which 1 token at genesis should have now is:
The term in the sum is the amount of stake one stake becomes due to inflation, multiplied by the amount of fees per stake.
Now we cast this into the period frame of view.
Recall that we build the rewards by creating a state entry for the rewards of the previous period, and keeping track of the rewards within this period.
Thus we first define the correct amount of rewards for each successive period, proving correctness of this via induction.
We then show that the state entry that gets efficiently built up block by block is equal to this value for the latest period.
Let $start, end$ denote the start/end of a period.
Suppose that $\forall f > 0$, $Reward(end(f))$ is correctly constructed as
(With period 1 being defined as the period that has the first bond into it)
It must be shown that assuming the supposition $\forall f \leq f_0$, $$Reward(end(f_0+1))= Reward(end(f_0))+\sum_{i = start(f_0+1)}^{end(f_0+1)}\left(\prod_{j =0}^{i}1+ x_j \right)\frac{R_i}{n_i}$$
Using the definition of $Reward$, it follows that:
Thus every block, each validator just has to add the total amount of fees (The $R_i$ term) that goes to delegates to some per-period term.
When creating a new period, $n_{start(f)}$ can be cached in state, and the product is already stored in the previous periods state entry.
You then get the next period's $n_{start(f)}$ from the current tm-power entry.
This is thus extremely efficient per block.
When withdrawing, you take the difference as before,
which yields the amount of rewards you would have obtained with $(\prod_0^{begin\ bonding\ period}1+ x)$ stake from the block you began bonding at until now.
$(\prod_0^{begin\ bonding\ period}1+ x)$ is known, since its included in the state entry for when you bonded.
You then divide the entitled fees by $(\prod_0^{begin\ bonding\ period}1+ x)$ to normalize it to being the amount of rewards you're entitled to from 1 stake at that block to now.
Then as before, you multiply by the amount of stake you had initially bonded.
TODO: (Does the difference equating to that make sense, or should it be shown explicitly)
Note that the inflation function could vary per block,
and per validator if ever a need rose.
If the inflation rate is the same for everyone then there can be a single global store for the entries corresponding to the product of inflations.
Inflation creation can trivially be epoched as long as inflation isn't required within the epoch, through changes to the $inflation$ function.
Again note that this process is extremely efficient.
\subsection{Withdrawing with no iteration over slashes}
TODO: Fill this out.
Core idea: you use the same mechanism as previously, but you just make that blocks $x_j$ term negative.
(So a $20\%$ slash would be equivalent to an inflation on that validator of $-20\%$)
This foregoes the constant inflation per validator, may or may not be worth it depending on expected number of slashes
\subsection{Auto bonding fees}
TODO: Fill this out.
Core idea: you use the same mechanism as previously, but you just don't take that optimization with $n_{i}$ and the $n_{start}$ relation.
This is an extremely simple scheme with many nice benefits.
\begin{itemize}
\item The overhead per block is a simple iteration over the bonded validator set, which occurs anyway. (Thus it can be implemented ``for-free" with an optimized code-base)
\item Withdrawing earned fees only requires iterating over slashes since when you bonded. (Which is a negligible iteration)
\item There are no approximations in any of the calculations. (modulo minor errata resulting from fixed precision decimals used in divisions)
\item Supports arbitrary inflation models. (Thus could even vary upon block signers)
\item Supports arbitrary fee distribution amongst the validator set. (Thus can account for things like only online validators get fees, which has important incentivization impacts)
\item The above two can change on a live chain with no issues.
\item Validator commission rates can be changed every block
\item The simplicity of this scheme lends itself well to implementation
\end{itemize}
Thus this scheme has efficiency improvements, simplicity improvements, and expressiveness improvements over the currently proposed schemes. With a correct fee distribution amongst the validator set, this solves the existing problem where one could withhold their signature for risk-free gain.
\item Determine if auto-bonding fees is compatible with inflation and comission rates in conjunction
\item mention storage optimization in the uniform inflation and iteration over slashing case: only have one storage location w/ refcount of the product of inflation results
\item Remove iteration over slashes by the same normalization trick used in inflation
\item Add equation numbers
\item perhaps re-organize so that the no iteration