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 #124

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
1 change: 1 addition & 0 deletions packages/apps-config/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
"@pendulum-chain/type-definitions": "0.3.8",
"@phala/typedefs": "0.2.33",
"@polkadot/api": "^10.11.2",
"@polkadot/api-base": "^10.11.2",
"@polkadot/api-derive": "^10.11.2",
"@polkadot/networks": "^12.6.2",
"@polkadot/react-identicon": "^3.6.4",
Expand Down
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;
}
10 changes: 10 additions & 0 deletions packages/apps-config/src/api/spec/aleph-zero.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,16 @@ export default {
description: '',
params: [],
type: 'u32'
},
yearly_inflation: {
description: 'Returns inflation from now to now + one year.',
params: [],
type: 'Perbill'
},
current_era_payout: {
description: 'Returns payout. First tuple item is a validators payout, second is the rest.',
params: [],
type: '(Balance, Balance)'
}
},
version: 1
Expand Down
10 changes: 10 additions & 0 deletions packages/apps-config/src/api/typesBundle.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,16 @@ export const typesBundle = {
"description": "",
"params": [],
"type": "u32"
},
"yearly_inflation": {
"description": "Returns inflation from now to now + one year.",
"params": [],
"type": "Perbill"
},
"current_era_payout": {
"description": "Returns payout. First tuple item is a validators payout, second is the rest.",
"params": [],
"type": "(Balance, Balance)"
}
},
"version": 1
Expand Down
20 changes: 20 additions & 0 deletions packages/apps-config/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,26 @@
// Copyright 2017-2024 @polkadot/apps-config authors & contributors
// SPDX-License-Identifier: Apache-2.0

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;
};
}
}

export interface TOptions {
ns?: string;
replace?: Record<string, unknown>
Expand Down
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": ""
}
}
youPickItUp marked this conversation as resolved.
Show resolved Hide resolved
10 changes: 9 additions & 1 deletion packages/page-explorer/src/Summary.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import React from 'react';

import { CardSummary, SummaryBox } from '@polkadot/react-components';
import { useApi } from '@polkadot/react-hooks';
import { BestFinalized, BestNumber, BlockToTime, TimeNow, TotalInactive, TotalIssuance } from '@polkadot/react-query';
import { AzeroCap, BestFinalized, BestNumber, BlockToTime, TimeNow, TotalInactive, TotalIssuance } from '@polkadot/react-query';
import { BN_ONE, formatNumber } from '@polkadot/util';

import SummarySession from './SummarySession.js';
Expand Down Expand Up @@ -43,6 +43,14 @@ function Summary ({ eventCount }: Props): React.ReactElement {
>
<TotalIssuance />
</CardSummary>
{api.query.aleph.azeroCap && (
<CardSummary
className='media--800'
label={t('max issuance')}
>
<AzeroCap />
</CardSummary>
)}
{!!api.query.balances.inactiveIssuance && (
<CardSummary
className='media--1300'
Expand Down
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
96 changes: 62 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,92 @@ 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);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);

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);
33 changes: 33 additions & 0 deletions packages/react-query/src/AzeroCap.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2017-2024 @polkadot/react-query authors & contributors
// SPDX-License-Identifier: Apache-2.0

import React from 'react';

import { useApi, useCall } from '@polkadot/react-hooks';

import FormatBalance from './FormatBalance.js';

interface Props {
children?: React.ReactNode;
className?: string;
label?: React.ReactNode;
}

function TotalIssuance ({ children, className = '', label }: Props): React.ReactElement<Props> | null {
const { api } = useApi();
const azeroCap = useCall<string>(api.query.aleph.azeroCap);

return (
<div className={className}>
{label || ''}
<FormatBalance
className={azeroCap ? '' : '--tmp'}
value={azeroCap}
withSi
/>
{children}
</div>
);
}

export default React.memo(TotalIssuance);
1 change: 1 addition & 0 deletions packages/react-query/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0

export { default as Available } from './Available.js';
export { default as AzeroCap } from './AzeroCap.js';
export { default as BalanceFree } from './BalanceFree.js';
export { default as BalanceVoting } from './BalanceVoting.js';
export { default as BestFinalized } from './BestFinalized.js';
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1987,6 +1987,7 @@ __metadata:
"@pendulum-chain/type-definitions": "npm:0.3.8"
"@phala/typedefs": "npm:0.2.33"
"@polkadot/api": "npm:^10.11.2"
"@polkadot/api-base": "npm:^10.11.2"
"@polkadot/api-derive": "npm:^10.11.2"
"@polkadot/networks": "npm:^12.6.2"
"@polkadot/react-identicon": "npm:^3.6.4"
Expand Down