Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

L1-287: Update the front end to inflation changes #81

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 0 additions & 6 deletions src/config/networks.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
// Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import { BN, BN_MILLION } from '@polkadot/util';
import { DefaultParams } from 'consts';
import { ReactComponent as AzeroIconSVG } from 'img/a0_icon.svg';
import { ReactComponent as AzeroInlineSVG } from 'img/a0_inline.svg';
Expand Down Expand Up @@ -62,7 +61,6 @@ if (import.meta.env.VITE_DISABLE_MAINNET !== '1') {
params: {
...DefaultParams,
stakeTarget: 0.5,
yearlyInflationInTokens: BN_MILLION.mul(new BN(30)).toNumber(),
},
defaultFeeReserve: 0.1,
} as const;
Expand Down Expand Up @@ -122,7 +120,6 @@ if (import.meta.env.VITE_DISABLE_TESTNET !== '1') {
params: {
...DefaultParams,
stakeTarget: 0.5,
yearlyInflationInTokens: BN_MILLION.mul(new BN(30)).toNumber(),
},
defaultFeeReserve: 0.1,
} as const;
Expand Down Expand Up @@ -181,7 +178,6 @@ if (import.meta.env.VITE_ENABLE_CUSTOM_NETWORK === '1') {
params: {
...DefaultParams,
stakeTarget: 0.5,
yearlyInflationInTokens: BN_MILLION.mul(new BN(30)).toNumber(),
},
defaultFeeReserve: 0.1,
} as const;
Expand Down Expand Up @@ -241,7 +237,6 @@ if (import.meta.env.VITE_DISABLE_DEVNET !== '1') {
params: {
...DefaultParams,
stakeTarget: 0.5,
yearlyInflationInTokens: BN_MILLION.mul(new BN(30)).toNumber(),
},
defaultFeeReserve: 0.1,
} as const;
Expand Down Expand Up @@ -301,7 +296,6 @@ if (import.meta.env.MODE === 'development') {
params: {
...DefaultParams,
stakeTarget: 0.5,
yearlyInflationInTokens: BN_MILLION.mul(new BN(30)).toNumber(),
},
defaultFeeReserve: 0.1,
} as const;
Expand Down
1 change: 1 addition & 0 deletions src/contexts/Api/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ if (!isValidConfiguredNetworkName(cachedNetworkName)) {
}

export const consts: APIConstants = {
chainDecimals: 12,
bondDuration: new BigNumber(0),
maxNominations: new BigNumber(0),
sessionsPerEra: new BigNumber(0),
Expand Down
7 changes: 6 additions & 1 deletion src/contexts/Api/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ import type { AnyApi, NetworkName } from 'types';
import { useEffectIgnoreInitial } from '@polkadot-cloud/react/hooks';
import * as defaults from './defaults';
import { defaultNetworkName } from './defaults';
import typesBundle from './typesBundle';

export const APIProvider = ({ children }: { children: React.ReactNode }) => {
// Get the initial network and prepare meta tags if necessary.
Expand Down Expand Up @@ -182,7 +183,10 @@ export const APIProvider = ({ children }: { children: React.ReactNode }) => {
if (!provider) return;

// initiate new api and set connected.
const newApi = await ApiPromise.create({ provider });
const newApi = await ApiPromise.create({
provider,
typesBundle,
});

// set connected here in case event listeners have not yet initialised.
setApiStatus('connected');
Expand Down Expand Up @@ -271,6 +275,7 @@ export const APIProvider = ({ children }: { children: React.ReactNode }) => {
const expectedEraTime = FallbackExpectedEraTime;

setConsts({
chainDecimals: newApi.registry.chainDecimals[0],
bondDuration,
maxNominations,
sessionsPerEra,
Expand Down
1 change: 1 addition & 0 deletions src/contexts/Api/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ export interface NetworkState {
meta: Network;
}
export interface APIConstants {
chainDecimals: number;
bondDuration: BigNumber;
maxNominations: BigNumber;
sessionsPerEra: BigNumber;
Expand Down
22 changes: 22 additions & 0 deletions src/contexts/Api/typesBundle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
const typesBundle = {
spec: {
'aleph-node': {
runtime: {
AlephSessionApi: [
{
methods: {
yearly_inflation: {
description: 'Returns inflation from now to now + one year.',
params: [],
type: 'Perbill',
},
},
version: 1,
},
],
},
},
},
};

export default typesBundle;
2 changes: 2 additions & 0 deletions src/contexts/Network/defaults.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ export const activeEra: ActiveEra = {
index: new BigNumber(0),
start: new BigNumber(0),
};

export const metrics: NetworkMetrics = {
azeroCap: new BigNumber(0),
totalIssuance: new BigNumber(0),
auctionCounter: new BigNumber(0),
earliestStoredSession: new BigNumber(0),
Expand Down
4 changes: 3 additions & 1 deletion src/contexts/Network/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,12 +40,14 @@ export const NetworkMetricsProvider = ({
const subscribeToMetrics = async () => {
const unsub = await api.queryMulti(
[
api.query.aleph.azeroCap,
api.query.balances.totalIssuance,
api.query.staking.minimumActiveStake,
],
([totalIssuance, minimumActiveStake]: AnyApi) => {
([azeroCap, totalIssuance, minimumActiveStake]: AnyApi) => {
setStateWithRef(
{
azeroCap: new BigNumber(azeroCap.toString()),
totalIssuance: new BigNumber(totalIssuance.toString()),
auctionCounter: metrics.auctionCounter,
earliestStoredSession: metrics.earliestStoredSession,
Expand Down
1 change: 1 addition & 0 deletions src/contexts/Network/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export interface NetworkMetricsContextInterface {
}

export interface NetworkMetrics {
azeroCap: BigNumber;
totalIssuance: BigNumber;
auctionCounter: BigNumber;
earliestStoredSession: BigNumber;
Expand Down
19 changes: 17 additions & 2 deletions src/library/Hooks/useFillVariables/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,12 @@ import { capitalizeFirstLetter, planckToUnit } from '@polkadot-cloud/utils';
import { useApi } from 'contexts/Api';
import { useNetworkMetrics } from 'contexts/Network';
import { usePoolsConfig } from 'contexts/Pools/PoolsConfig';
import type { AnyJson } from 'types';
import type { AnyJson, NetworkName } from 'types';

const networkToFirstYearInflation: Partial<Record<NetworkName, string>> = {
'Aleph Zero': '27M',
'Aleph Zero Testnet': '1000M',
};

export const useFillVariables = () => {
const { network, consts } = useApi();
Expand All @@ -17,7 +22,7 @@ export const useFillVariables = () => {
} = consts;
const { minJoinBond, minCreateBond } = stats;
const { metrics } = useNetworkMetrics();
const { minimumActiveStake } = metrics;
const { azeroCap, minimumActiveStake } = metrics;

const fillVariables = (d: AnyJson, keys: string[]) => {
const fields: AnyJson = Object.entries(d).filter(([k]: any) =>
Expand All @@ -26,6 +31,16 @@ export const useFillVariables = () => {
const transformed = Object.entries(fields).map(
([, [key, val]]: AnyJson) => {
const varsToValues = [
[
'{AZERO_CAP}',
azeroCap
.shiftedBy(-(consts.chainDecimals + 6))
.toFormat({ suffix: 'M' }),
],
[
'{INFLATION_FIRST_YEAR}',
networkToFirstYearInflation[network.name] ?? '-M',
],
['{NETWORK_UNIT}', network.unit],
['{NETWORK_NAME}', capitalizeFirstLetter(network.name)],
[
Expand Down
99 changes: 47 additions & 52 deletions src/library/Hooks/useInflation/index.tsx
Original file line number Diff line number Diff line change
@@ -1,70 +1,65 @@
// Copyright 2023 @paritytech/polkadot-staking-dashboard authors & contributors
// SPDX-License-Identifier: GPL-3.0-only

import BigNumber from 'bignumber.js';
import type BigNumber from 'bignumber.js';
import { useApi } from 'contexts/Api';
import { useNetworkMetrics } from 'contexts/Network';
import { useStaking } from 'contexts/Staking';
import { useEffect, useState } from 'react';

const BIGNUMBER_THOUSAND = new BigNumber(1_000);
const BIGNUMBER_MILLION = new BigNumber(1_000_000);
const BIGNUMBER_BILLION = new BigNumber(1_000_000_000);

export const useInflation = () => {
const { network } = useApi();
const { metrics } = useNetworkMetrics();
const { staking } = useStaking();
const { params } = network;
const { lastTotalStake } = staking;
const { totalIssuance, auctionCounter } = metrics;

const {
auctionAdjust,
auctionMax,
maxInflation,
stakeTarget,
yearlyInflationInTokens,
} = params;
const calculateInflation = (
totalStaked: BigNumber,
totalIssuance: BigNumber,
yearlyInflationInPercentage: number
) => {
const stakedFraction =
totalStaked.isZero() || totalIssuance.isZero()
? 0
: totalStaked.dividedBy(totalIssuance).toNumber();

const baseStakedReturn =
stakedFraction !== 0 ? yearlyInflationInPercentage / stakedFraction : 0;
/* For Aleph Zero inflation is calculated based on yearlyInflationInTokens and totalIssuanceInTokens
* We multiply stakedReturn by 0.9, as in case of Aleph Zero chain 10% of return goes to treasury
*/
const stakedReturn = baseStakedReturn * 0.9;

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

const calculateInflation = (
totalStaked: BigNumber,
numAuctions: BigNumber
) => {
const stakedFraction =
totalStaked.isZero() || totalIssuance.isZero()
? 0
: totalStaked
.multipliedBy(BIGNUMBER_MILLION)
.dividedBy(totalIssuance)
.toNumber() / BIGNUMBER_MILLION.toNumber();
const idealStake =
stakeTarget -
Math.min(auctionMax, numAuctions.toNumber()) * auctionAdjust;
const idealInterest = maxInflation / idealStake;
const useYearlyInflation = () => {
const { api } = useApi();
const [yearlyInflation, setYearlyInflation] = useState<number>();

const totalIssuanceInTokens = totalIssuance
.div(BIGNUMBER_BILLION)
.div(BIGNUMBER_THOUSAND);
const getYearlyInflation = api?.call?.alephSessionApi?.yearlyInflation;

const inflation = totalIssuanceInTokens.isZero()
? 0
: 100 * (yearlyInflationInTokens / totalIssuanceInTokens.toNumber());
useEffect(() => {
getYearlyInflation?.()
.then((val) => setYearlyInflation(val.toNumber() / 1_000_000_000))
// eslint-disable-next-line no-console
.catch(console.error);
// `api` object can change in case of network change which should trigger refetch.
}, [api]);

let stakedReturn = stakedFraction ? inflation / stakedFraction : 0;
stakedReturn *= 0.9;
return yearlyInflation;
};

return {
idealInterest,
idealStake,
youPickItUp marked this conversation as resolved.
Show resolved Hide resolved
inflation,
stakedFraction,
stakedReturn,
};
};
export const useInflation = () => {
const {
metrics: { totalIssuance },
} = useNetworkMetrics();
const {
staking: { lastTotalStake },
} = useStaking();
const yearlyInflation = useYearlyInflation();

return calculateInflation(lastTotalStake, auctionCounter);
return calculateInflation(
lastTotalStake,
totalIssuance,
(yearlyInflation ?? 0) * 100
);
};
4 changes: 2 additions & 2 deletions src/locale/cn/help.json
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@
"inflation": [
"通货膨胀",
[
"{NETWORK_UNIT}具有通货膨胀性.所以无封顶数量.",
"在验证人的奖励是基于抵押金额, 其余归国库所有的情况下, 每年通货膨胀率约为10%."
"{NETWORK_UNIT} is inflationary. Inflation is exponentially decreasing, starting at {INFLATION_FIRST_YEAR} {NETWORK_UNIT} emission in the first year.",
"The max supply is {AZERO_CAP} {NETWORK_UNIT}."
]
],
"lastEraPayout": [
Expand Down
4 changes: 2 additions & 2 deletions src/locale/en/help.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,8 +108,8 @@
"inflation": [
"Inflation",
[
"{NETWORK_UNIT} is inflationary; there is no maximum number of {NETWORK_UNIT}.",
"Inflation is fixed to 30M {NETWORK_UNIT} tokens annually. This translates to 10% inflation right after launch and slowly decreasing to 0%."
"{NETWORK_UNIT} is inflationary. Inflation is exponentially decreasing, starting at {INFLATION_FIRST_YEAR} {NETWORK_UNIT} emission in the first year.",
"The max supply is {AZERO_CAP} {NETWORK_UNIT}."
]
],
"lastEraPayout": [
Expand Down
23 changes: 23 additions & 0 deletions src/types/@polkadot/api-base.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type {
ApiTypes,
AugmentedCall,
DecoratedCallBase,
} from '@polkadot/api-base/types';
import type { Perbill } from '@polkadot/types/interfaces/runtime';
import type { Observable } from '@polkadot/types/types';

declare module '@polkadot/api-base/types/calls' {
interface AugmentedCalls<ApiType extends ApiTypes> {
/** 0xbc9d89904f5b923f/1 */
alephSessionApi?: {
/**
* The API to query account nonce (aka transaction index)
* */
yearlyInflation?: AugmentedCall<ApiType, () => Observable<Perbill>>;
/**
* Generic call
* */
[key: string]: DecoratedCallBase<ApiType> | undefined;
};
}
}