Author: [M.Sc. Harald Heckmann (sea212)](https://github.com/sea212) Reviewers: [B.Sc. Christopher Altmann](https://github.com/Chralt98) Revision: 3 # Collator system inflation This documents purpose is to determine a sensible inflation configuration for the collation system. It should respect the following constraints: 1. The inflation provided to the collation system must keep collation profitable 2. The inflation provided to the collation system must be lower than the inflation assigned to the court system and the liquidity system, as they include higher risks. 3. The inflation should be economically reasonable, ideally it is counter-balanced by a proper burn-rate. ## Introduction As Zeitgeist plans to incentivize participation in other systems of the protocol than the collation system, it is time to determine reasonable values for inflation. The yearly inflation that is generated for the collation system is calculated in the [`parachain-staking`](https://docs.moonbeam.network/builders/pallets-precompiles/pallets/staking/) pallet. We define a formula to calculate the rewards per month in dollars: At any given time, let $T$ be the current total supply in ZTG, $I$ the total yearly inflation, $C$ the current collator commission, $S$ the active collator set size and $P$ the 30-day moving average of the ZTG price. Then the formula to calculate the monthly rewards $R$ per collator is: $$ R = \frac{TICP}{12S} $$ ## Current collator rewards $T = 103195502$ ZTG, based on the storage call [`balances.totalIssuance`](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fmain.rpc.zeitgeist.pm%2Fws#/chainstate) $I = 5\%$, based on the storage call [`parachainStaking.inflationConfig`](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fmain.rpc.zeitgeist.pm%2Fws#/chainstate) $C = 20\%$, based on the storage call [`parachainStaking.collatorCommission`](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fmain.rpc.zeitgeist.pm%2Fws#/chainstate) $S = 28$, based on the storage call [`parachainStaking.totalSelected`](https://polkadot.js.org/apps/?rpc=wss%3A%2F%2Fmain.rpc.zeitgeist.pm%2Fws#/chainstate) $P = 0.08861$ $/ZTG, based on the [exchange with the highest volume](https://www.mexc.com/exchange/ZTG_USDT) of ZTG at the given time Thus the current monthly reward in dollars per month per collator is: $$ R = \frac{103195502 \cdot 0.05 \cdot 0.2 \cdot 0.8861}{12 \cdot 28} \approx 272 $$ ## Adjusting the rewards There are three plausible ways to adjust the rewards: 1. Change the yearly inflation $I$, that is assigned to the collation system. 2. Change the collator commission $C$ 3. Change the active collator set size $S$ As the goal is to redistribute inflation to other systems within the protocol, the parameter $I$ has to be reduced. It is not desired to reduce the active collator set size ("kick out" collators), so $S$ is out of question. By increasing the collator commission $C$, the reward pool could be further shifted from the delegators to the collators, effectively increasing the margin to reduce $I$. However, with the current configuration, $C$ is already set to $20\%$, which is a rather big portion of the designated inflation. ## Calculating a sensible yearly inflation By rearranging the formula $R$, we can figure out a reasonable yearly inflation $I$ based on the remaining parameters, especially the monthly gain $R$ per collator. $$ R = \frac{TICP}{12S}\\ I = \frac{12RS}{TCP} $$ ## Programatically inspecting reward to inflation relationship The following program calculates the yearly inflation $I$ in a given range of expected returns per month for collators: ```python #!/usr/bin/python3 import matplotlib.pyplot as plt import mplcursors def find_inflation(monthly_rewards_dollar): t=103000000 p=0.08861 c=0.2 s=28 return monthly_rewards_dollar * s * 12 / (t * p * c) def plot(keyval): plt.plot(list(keyval.keys()), list(keyval.values())) plt.xlabel('Estimated reward per month in USD') plt.ylabel('Percent inflation per year caused by the collation system') plt.title('Collator reward per inflation') # display value on hover using mplcursors library cursor = mplcursors.cursor() cursor.connect('add', lambda sel: sel.annotation.set_text(f'Inflation: {sel.target[1]:.2f}%')) plt.show() def scan_inflations(minimum, maximum, step): results = {} for reward in range(minimum, maximum+step, step): inflation = find_inflation(reward) * 100 # use precentage representation results[reward] = inflation print("${} / month: {} %".format(reward, inflation)) return results if __name__=="__main__": from sys import argv,exit if len(argv) != 4: print("Syntax: ./find_inflation <min_reward_month> <max_reward_month> <step_size>") exit(1) _, minimum, maximum, step = argv result = scan_inflations(int(minimum), int(maximum), int(step)) plot(result) ``` Syntax: `./find_inflation <min_reward_month> <max_reward_month> <step>` For `min_reward_month=50`, `max_reward_month=150`, `step_size=10`, the results are as follows: > $50 / month: 0.9203633682231399 % $60 / month: 1.104436041867768 % $70 / month: 1.2885087155123958 % $80 / month: 1.4725813891570239 % $90 / month: 1.656654062801652 % $100 / month: 1.8407267364462798 % $110 / month: 2.0247994100909077 % $120 / month: 2.208872083735536 % $130 / month: 2.392944757380164 % $140 / month: 2.5770174310247915 % $150 / month: 2.7610901046694196 % ![Zeitgeist relaychain](https://drive.google.com/uc?id=1LrTm8bcDgHsXe7nvnSrq6UcJUDJil7SQ&export=download )