Skip to content

Commit

Permalink
L1-287: Change inflation calculations
Browse files Browse the repository at this point in the history
  • Loading branch information
youPickItUp committed Oct 8, 2024
1 parent 55ffa75 commit 5e05d35
Show file tree
Hide file tree
Showing 5 changed files with 68 additions and 52 deletions.
19 changes: 4 additions & 15 deletions packages/apps-config/src/api/params/inflation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@

import type { ApiPromise } from '@polkadot/api';

import { BN, BN_MILLION } from '@polkadot/util';

import { ALEPHZERO_MAINNET_GENESIS, ALEPHZERO_TESTNET_GENESIS, CERE_NETWORK_GENESIS, CERE_NETWORK_TESTNET_GENESIS, DOCK_POS_TESTNET_GENESIS, KUSAMA_GENESIS, NEATCOIN_GENESIS, NFTMART_GENESIS, POLKADOT_GENESIS, VARA_NETWORK_GENESIS, VARA_NETWORK_TESTNET_GENESIS } from '../constants.js';

export interface InflationParams {
Expand All @@ -16,10 +14,6 @@ export interface InflationParams {
stakeTarget: number;
}

interface UniformEraPayoutInflationParams extends InflationParams {
yearlyInflationInTokens: BN;
}

const DEFAULT_PARAMS: InflationParams = {
auctionAdjust: 0,
auctionMax: 0,
Expand All @@ -33,18 +27,13 @@ const DEFAULT_PARAMS: InflationParams = {
stakeTarget: 0.5
};

const DEFAULT_UNIFORM_ERA_PAYOUT_PARAMS: UniformEraPayoutInflationParams = {
...DEFAULT_PARAMS,
yearlyInflationInTokens: BN_MILLION.mul(new BN(30))
};

const CERE_NETWORK_INFLATION_PARAMS = { ...DEFAULT_PARAMS, maxInflation: 0.05, minInflation: 0.0001, stakeTarget: 0.2 };

const VARA_NETWORK_INFLATION_PARAMS = { ...DEFAULT_PARAMS, maxInflation: 0, minInflation: 0.0001, stakeTarget: 0.85 };

const KNOWN_PARAMS: Record<string, InflationParams> = {
[ALEPHZERO_MAINNET_GENESIS]: DEFAULT_UNIFORM_ERA_PAYOUT_PARAMS,
[ALEPHZERO_TESTNET_GENESIS]: DEFAULT_UNIFORM_ERA_PAYOUT_PARAMS,
[ALEPHZERO_MAINNET_GENESIS]: DEFAULT_PARAMS,
[ALEPHZERO_TESTNET_GENESIS]: DEFAULT_PARAMS,
[CERE_NETWORK_GENESIS]: CERE_NETWORK_INFLATION_PARAMS,
[CERE_NETWORK_TESTNET_GENESIS]: CERE_NETWORK_INFLATION_PARAMS,
[DOCK_POS_TESTNET_GENESIS]: { ...DEFAULT_PARAMS, stakeTarget: 0.75 },
Expand All @@ -60,8 +49,8 @@ const KNOWN_PARAMS: Record<string, InflationParams> = {
[VARA_NETWORK_TESTNET_GENESIS]: VARA_NETWORK_INFLATION_PARAMS
};

export function getInflationParams (api: ApiPromise): InflationParams | UniformEraPayoutInflationParams {
export function getInflationParams (api: ApiPromise): InflationParams {
// below behaviour is different between our fork and upstream, that by default we are operating
// in uniform era payout model, rather than Polkadot-js's RewardCurve model
return KNOWN_PARAMS[api.genesisHash.toHex()] || DEFAULT_UNIFORM_ERA_PAYOUT_PARAMS;
return KNOWN_PARAMS[api.genesisHash.toHex()] || DEFAULT_PARAMS;
}
1 change: 1 addition & 0 deletions packages/apps/public/locales/en/app-explorer.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@
"last events": "last events",
"logs": "logs",
"max": "max",
"max issuance": "max issuance",
"min": "min",
"mortal, valid from #{{startAt}} to #{{endsAt}}": "mortal, valid from #{{startAt}} to #{{endsAt}}",
"no": "no",
Expand Down
3 changes: 2 additions & 1 deletion packages/apps/public/locales/en/translation.json
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,7 @@
"max RefTime allowed (M, {{estimatedRefTime}} estimated)": "",
"max gas allowed (M)": "",
"max gas allowed (M, {{estimatedMg}} estimated)": "",
"max issuance": "",
"max read gas": "",
"max. members": "",
"max. members / pool": "",
Expand Down Expand Up @@ -1899,4 +1900,4 @@
"{{value}}x voting balance, locked for {{duration}}x duration{{period}}": "",
"{{when}} (est.)": "",
"⚡️ Thunder Gateway": ""
}
}
2 changes: 0 additions & 2 deletions packages/react-hooks/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,6 @@ export interface ModalState {
}

export interface Inflation {
idealStake: number;
idealInterest: number;
inflation: number;
stakedFraction: number;
stakedReturn: number;
Expand Down
95 changes: 61 additions & 34 deletions packages/react-hooks/src/useInflation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,13 @@ import type { Inflation } from './types.js';
import { useEffect, useState } from 'react';

import { getInflationParams } from '@polkadot/apps-config';
import { BN_BILLION, BN_MILLION, BN_ZERO } from '@polkadot/util';
import { BN_THOUSAND } from '@polkadot/util/bn/consts';
import { BN_MILLION, BN_ZERO, isFunction } from '@polkadot/util';

import { createNamedHook } from './createNamedHook.js';
import { useApi } from './useApi.js';
import { useCall } from './useCall.js';

const EMPTY: Inflation = { idealInterest: 0, idealStake: 0, inflation: 0, stakedFraction: 0, stakedReturn: 0 };

function calcInflationUniformEraPayout (totalIssuance: BN, yearlyInflationInTokens: BN): number {
const totalIssuanceInTokens = totalIssuance.div(BN_BILLION).div(BN_THOUSAND);

return (totalIssuanceInTokens.isZero() ? 0.0 : yearlyInflationInTokens.toNumber() / totalIssuanceInTokens.toNumber());
}
const EMPTY: Inflation = { inflation: 0, stakedFraction: 0, stakedReturn: 0 };

function calcInflationRewardCurve (minInflation: number, stakedFraction: number, idealStake: number, idealInterest: number, falloff: number) {
return (minInflation + (
Expand All @@ -31,57 +24,91 @@ function calcInflationRewardCurve (minInflation: number, stakedFraction: number,
));
}

function calcInflation (api: ApiPromise, totalStaked: BN, totalIssuance: BN, numAuctions: BN): Inflation {
const inflationParams = getInflationParams(api);
const { auctionAdjust, auctionMax, falloff, maxInflation, minInflation, stakeTarget } = inflationParams;
const stakedFraction = totalStaked.isZero() || totalIssuance.isZero()
? 0
: totalStaked.mul(BN_MILLION).div(totalIssuance).toNumber() / BN_MILLION.toNumber();
function calcInflationOnNonAleph (api: ApiPromise, stakedFraction: number, numAuctions: BN): Inflation {
const { auctionAdjust, auctionMax, falloff, maxInflation, minInflation, stakeTarget } = getInflationParams(api);

const idealStake = stakeTarget - (Math.min(auctionMax, numAuctions.toNumber()) * auctionAdjust);
const idealInterest = maxInflation / idealStake;
let inflationInPercentage = 0;

if ('yearlyInflationInTokens' in inflationParams) {
inflationInPercentage = 100 * calcInflationUniformEraPayout(totalIssuance, inflationParams.yearlyInflationInTokens);
} else {
inflationInPercentage = 100 * calcInflationRewardCurve(minInflation, stakedFraction, idealStake, idealInterest, falloff);
}
const inflationInPercentage = 100 * calcInflationRewardCurve(minInflation, stakedFraction, idealStake, idealInterest, falloff);

let stakedReturn = stakedFraction
const stakedReturn = stakedFraction
? (inflationInPercentage / stakedFraction)
: 0;

return {
inflation: inflationInPercentage,
stakedFraction,
stakedReturn
};
}

function calcInflationOnAleph (yearlyInflationInPercentage: number, stakedFraction: number) {
const baseStakedReturn = stakedFraction !== 0
? (yearlyInflationInPercentage / stakedFraction)
: 0;

// Here we multiply stakedReturn by 0.9, as in case of Aleph Zero chain 10% of return goes to treasury
if ('yearlyInflationInTokens' in inflationParams) {
stakedReturn *= 0.9;
}
const stakedReturn = baseStakedReturn * 0.9;

return {
idealInterest,
idealStake,
inflation: inflationInPercentage,
inflation: yearlyInflationInPercentage,
stakedFraction,
stakedReturn
};
}

function useYearlyInflation () {
const { api } = useApi();

const [yearlyInflation, setYearlyInflation] = useState<number>();

const getYearlyInflation = api.call?.alephSessionApi?.yearlyInflation;

useEffect(() => {
getYearlyInflation?.().then((val) => {
setYearlyInflation(val.toNumber() / 1_000_000_000);
}).catch(console.error);
}, [getYearlyInflation]);

return { isSupported: isFunction(getYearlyInflation), yearlyInflation };
}

function useInflationImpl (totalStaked?: BN): Inflation {
const { api } = useApi();

const totalIssuance = useCall<BN>(api.query.balances?.totalIssuance);
const auctionCounter = useCall<BN>(api.query.auctions?.auctionCounter);
const [state, setState] = useState<Inflation>(EMPTY);
const { isSupported: isYearlyInflationApiSupported, yearlyInflation } = useYearlyInflation();

const [inflation, setInflation] = useState<Inflation>(EMPTY);

useEffect((): void => {
const numAuctions = api.query.auctions
? auctionCounter
: BN_ZERO;

numAuctions && totalIssuance && totalStaked && setState(
calcInflation(api, totalStaked, totalIssuance, numAuctions)
);
}, [api, auctionCounter, totalIssuance, totalStaked]);
if (
numAuctions === undefined ||
totalStaked === undefined ||
totalIssuance === undefined ||
(isYearlyInflationApiSupported && yearlyInflation === undefined)
) {
return;
}

const stakedFraction = totalStaked.isZero() || totalIssuance.isZero()
? 0
: totalStaked.mul(BN_MILLION).div(totalIssuance).toNumber() / BN_MILLION.toNumber();

const inflation = isYearlyInflationApiSupported && yearlyInflation !== undefined
? calcInflationOnAleph(yearlyInflation * 100, stakedFraction)
: calcInflationOnNonAleph(api, stakedFraction, numAuctions);

setInflation(inflation);
}, [api, auctionCounter, isYearlyInflationApiSupported, totalIssuance, totalStaked, yearlyInflation]);

return state;
return inflation;
}

export const useInflation = createNamedHook('useInflation', useInflationImpl);

0 comments on commit 5e05d35

Please sign in to comment.