import type { TokenAmount } from "@saberhq/token-utils"; import { zip } from "lodash-es"; import type { ClaimableAmounts, GetAllClaimableAmounts } from "./types"; // number of ms in one year const ONE_YEAR_MS = 365 * 86_400 * 1_000; /** * Rewards per second */ export interface RewardRates { timeT0Ms: number; amountsT0: ClaimableAmounts; pools: (number | null)[]; total: number; } /** * Calculate the rewards per second of all pools/total * @returns */ export const calculateRewardRates = ( getAllClaimableAmounts: GetAllClaimableAmounts, msBetweenCheckpoints: number = ONE_YEAR_MS ): RewardRates | null => { const timeT0Ms = Date.now(); const amountsT0 = getAllClaimableAmounts(); const amountsT1 = getAllClaimableAmounts(msBetweenCheckpoints); if (!amountsT0 || !amountsT1) { return null; } return { timeT0Ms, amountsT0, pools: zip(amountsT0.allClaimable, amountsT1.allClaimable).map( ([amt0, amt1]) => { if (!amt0 || !amt1) { return null; } return calculateRewardsPerSecond(amt0, amt1, msBetweenCheckpoints); } ), total: amountsT0.sum && amountsT1.sum ? calculateRewardsPerSecond( amountsT0.sum, amountsT1.sum, msBetweenCheckpoints ) : 0, }; }; const calculateRewardsPerSecond = ( t0: TokenAmount, t1: TokenAmount, msBetweenCheckpoints: number ): number => { const t0Float = parseFloat(t0.toExact()); const t1Float = parseFloat(t1.toExact()); return ((t1Float - t0Float) / msBetweenCheckpoints) * 1_000; };