Add missing commission to payout calculations (#2051)
* Add missing comission to payout calcs * yarn * Bump dev with version update fix
This commit is contained in:
@@ -0,0 +1,48 @@
|
||||
// Copyright 2017-2020 @polkadot/api-derive authors & contributors
|
||||
// This software may be modified and distributed under the terms
|
||||
// of the Apache-2.0 license. See the LICENSE file for details.
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { EraIndex, ValidatorPrefs } from '@polkadot/types/interfaces';
|
||||
import { DeriveEraPrefs, DeriveEraValPrefs } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable, combineLatest, of } from 'rxjs';
|
||||
import { map, switchMap } from 'rxjs/operators';
|
||||
import { StorageKey } from '@polkadot/types';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type KeysAndPrefs = [StorageKey, ValidatorPrefs][];
|
||||
|
||||
function mapPrefs (era: EraIndex, all: KeysAndPrefs): DeriveEraPrefs {
|
||||
const validators: DeriveEraValPrefs = {};
|
||||
|
||||
all.forEach(([key, prefs]): void => {
|
||||
validators[key.args[1].toString()] = prefs;
|
||||
});
|
||||
|
||||
return { era, validators };
|
||||
}
|
||||
|
||||
export function eraPrefs (api: ApiInterfaceRx): (era: EraIndex) => Observable<DeriveEraPrefs> {
|
||||
return memo((era: EraIndex): Observable<DeriveEraPrefs> =>
|
||||
api.query.staking.erasValidatorPrefs.entries(era).pipe(
|
||||
map((prefs) => mapPrefs(era, prefs))
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
export function erasPrefs (api: ApiInterfaceRx): (withActive?: boolean | BN | number) => Observable<DeriveEraPrefs[]> {
|
||||
return memo((withActive?: boolean | BN | number): Observable<DeriveEraPrefs[]> =>
|
||||
api.derive.staking.erasHistoric(withActive).pipe(
|
||||
switchMap((eras): Observable<DeriveEraPrefs[]> =>
|
||||
eras.length
|
||||
? combineLatest(
|
||||
eras.map((era) => api.derive.staking.eraPrefs(era))
|
||||
)
|
||||
: of([])
|
||||
)
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -6,6 +6,7 @@ export * from './account';
|
||||
export * from './erasExposure';
|
||||
export * from './erasHistoric';
|
||||
export * from './erasPoints';
|
||||
export * from './erasPrefs';
|
||||
export * from './erasRewards';
|
||||
export * from './controllers';
|
||||
export * from './electedInfo';
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
import { ApiInterfaceRx } from '@polkadot/api/types';
|
||||
import { Balance } from '@polkadot/types/interfaces';
|
||||
import { DeriveEraPoints, DeriveEraRewards, DeriveStakerExposure, DeriveStakerReward } from '../types';
|
||||
import { DeriveEraPoints, DeriveEraPrefs, DeriveEraRewards, DeriveEraValPrefs, DeriveStakerExposure, DeriveStakerReward } from '../types';
|
||||
|
||||
import BN from 'bn.js';
|
||||
import { Observable, combineLatest } from 'rxjs';
|
||||
@@ -12,18 +12,24 @@ import { map } from 'rxjs/operators';
|
||||
|
||||
import { memo } from '../util';
|
||||
|
||||
type Result = [DeriveEraPoints[], DeriveEraRewards[], DeriveStakerExposure[]];
|
||||
const ZERO = new BN(0);
|
||||
type Result = [DeriveEraPoints[], DeriveEraPrefs[], DeriveEraRewards[], DeriveStakerExposure[]];
|
||||
|
||||
function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasRewards, exposures]: Result): DeriveStakerReward[] {
|
||||
const ZERO = new BN(0);
|
||||
const COMM_DIV = new BN(1_000_000_000);
|
||||
|
||||
function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasPrefs, erasRewards, exposures]: Result): DeriveStakerReward[] {
|
||||
return exposures.map(({ era, isEmpty, isValidator, nominating, validators: eraValidators }): DeriveStakerReward => {
|
||||
const { eraPoints, validators: allValPoints } = erasPoints.find((p) => p.era.eq(era)) || { eraPoints: new BN(0), validators: {} };
|
||||
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: new BN(0) };
|
||||
const { eraReward } = erasRewards.find((r) => r.era.eq(era)) || { eraReward: ZERO };
|
||||
const { validators: allValPrefs } = erasPrefs.find((p) => p.era.eq(era)) || { validators: {} as DeriveEraValPrefs };
|
||||
const validators: Record<string, Balance> = {};
|
||||
let total = ZERO;
|
||||
|
||||
Object.entries(eraValidators).forEach(([validatorId, exposure]): void => {
|
||||
const valPoints = allValPoints[validatorId] || new BN(0);
|
||||
const valPoints = allValPoints[validatorId] || ZERO;
|
||||
const valComm = allValPrefs[validatorId]?.commission.unwrap() || ZERO;
|
||||
const avail = eraReward.mul(valPoints).div(eraPoints);
|
||||
const valCut = valComm.mul(avail).div(COMM_DIV);
|
||||
const expTotal = exposure.total.unwrap();
|
||||
let value: BN | undefined;
|
||||
|
||||
@@ -40,7 +46,7 @@ function parseRewards (api: ApiInterfaceRx, stakerId: string, [erasPoints, erasR
|
||||
: ZERO;
|
||||
}
|
||||
|
||||
value = eraReward.mul(valPoints).mul(staked).div(eraPoints).div(expTotal);
|
||||
value = avail.sub(valCut).mul(staked).div(expTotal).add(validatorId === stakerId ? valCut : ZERO);
|
||||
total = total.add(value);
|
||||
}
|
||||
|
||||
@@ -64,6 +70,7 @@ export function stakerRewards (api: ApiInterfaceRx): (accountId: Uint8Array | st
|
||||
|
||||
return combineLatest([
|
||||
api.derive.staking.erasPoints(startEra),
|
||||
api.derive.staking.erasPrefs(startEra),
|
||||
api.derive.staking.erasRewards(startEra),
|
||||
api.derive.staking.stakerExposure(stakerId, startEra)
|
||||
]).pipe(
|
||||
|
||||
@@ -7,12 +7,19 @@ import { DeriveSessionIndexes } from '../session/types';
|
||||
|
||||
export type DeriveEraValPoints = Record<string, RewardPoint>;
|
||||
|
||||
export type DeriveEraValPrefs = Record<string, ValidatorPrefs>;
|
||||
|
||||
export interface DeriveEraPoints {
|
||||
era: EraIndex;
|
||||
eraPoints: RewardPoint;
|
||||
validators: DeriveEraValPoints;
|
||||
}
|
||||
|
||||
export interface DeriveEraPrefs {
|
||||
era: EraIndex;
|
||||
validators: DeriveEraValPrefs;
|
||||
}
|
||||
|
||||
export interface DeriveEraRewards {
|
||||
era: EraIndex;
|
||||
eraReward: Balance;
|
||||
|
||||
Reference in New Issue
Block a user