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

Updated /distribution endpoint #54

Merged
merged 5 commits into from
Nov 23, 2024
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
20 changes: 11 additions & 9 deletions packages/nimiq-rewards-calculator/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,23 +1,25 @@
import { posSupplyAt, SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE, SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE_TESTNET } from 'nimiq-supply-calculator'
import { posSupplyAt, PROOF_OF_STAKE_FORK_DATE, SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE, SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE_TESTNET } from 'nimiq-supply-calculator'

// = 1 - POS_SUPPLY_DECAY ** (1000 * 60 * 60 * 24)
const DECAY_PER_DAY = 0.0003432600460362

export interface CalculateStakingRewardsParams {
/**
* The initial amount of cryptocurrency staked, in NIM.
* The ratio of the total staked cryptocurrency to the total supply.
*/
amount: number
stakedSupplyRatio: number

/**
* The number of days the cryptocurrency is staked.
* The initial amount of cryptocurrency staked, in NIM.
* @default 1
*/
days: number
amount?: number

/**
* The ratio of the total staked cryptocurrency to the total supply.
* The number of days the cryptocurrency is staked.
* @default 365
*/
stakedSupplyRatio: number
days?: number

/**
* Indicates whether the staking rewards are restaked (default is true). Restaked mean that each staking reward is added to the pool of staked cryptocurrency for compound interest.
Expand Down Expand Up @@ -67,10 +69,10 @@ export interface CalculateStakingRewardsResult {
* @returns {CalculateStakingRewardsResult} The result of the calculation.
*/
export function calculateStakingRewards(params: CalculateStakingRewardsParams): CalculateStakingRewardsResult {
const { amount, days, autoRestake = true, stakedSupplyRatio, network = 'main-albatross', fee = 0 } = params
const { amount = 1e5, days = 365, autoRestake = true, stakedSupplyRatio, network = 'main-albatross', fee = 0 } = params
const genesisSupply = network === 'main-albatross' ? SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE : SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE_TESTNET

const initialRewardsPerDay = posSupplyAt(24 * 60 * 60 * 1000) - genesisSupply
const initialRewardsPerDay = posSupplyAt(PROOF_OF_STAKE_FORK_DATE.getTime() + 24 * 60 * 60 * 1000) - genesisSupply
const decayFactor = Math.E ** (-DECAY_PER_DAY * days)

let gainRatio = 0
Expand Down
2 changes: 1 addition & 1 deletion packages/nimiq-supply-calculator/src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ export const TOTAL_SUPPLY = 21e14
/**
* The date of the proof-of-stake fork.
*/
export const PROOF_OF_STAKE_FORK_DATE = new Date('2024-11-19')
export const PROOF_OF_STAKE_FORK_DATE = new Date('2024-11-19T16:45:20.000Z')

/**
* The total supply of the cryptocurrency at the proof-of-stake fork date, in NIM.
Expand Down
13 changes: 6 additions & 7 deletions packages/nimiq-supply-calculator/src/pos.ts
Original file line number Diff line number Diff line change
@@ -1,18 +1,17 @@
import { SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE, TOTAL_SUPPLY } from './constants'
import { PROOF_OF_STAKE_FORK_DATE, SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE, TOTAL_SUPPLY } from './constants'
import { powi } from './utils'

// Supply decay per millisecond
const SUPPLY_DECAY = 0.9999999999960264

/**
* Calculate the PoS supply at a given time.
* @param {number} timestampTs The timestamp at which to calculate the PoS supply.
* @param {number} timestampMs The timestamp at which to calculate the PoS supply.
* @returns {number} The total supply of the cryptocurrency at the given time, in NIM.
*/
export function posSupplyAt(timestampTs: number): number {
if (timestampTs < 0) {
export function posSupplyAt(timestampMs: number): number {
const ts = timestampMs - PROOF_OF_STAKE_FORK_DATE.getTime()
if (ts < 0)
throw new Error('currentTime must be greater or equal to genesisTime')
}

return (TOTAL_SUPPLY - ((TOTAL_SUPPLY - SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE * 1e5) * powi(SUPPLY_DECAY, timestampTs))) / 1e5 // Luna >> NIM
return (TOTAL_SUPPLY - ((TOTAL_SUPPLY - SUPPLY_AT_PROOF_OF_STAKE_FORK_DATE * 1e5) * powi(SUPPLY_DECAY, ts)))
}
10 changes: 5 additions & 5 deletions server/api/[version]/distribution.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ export default defineCachedEventHandler(async () => {
)
.get()

const staked = result?.totalStaked ?? 0
const staked = (result?.totalStaked ?? 0) * 1e5
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The totalStaked stored in the database is in NIM not Lunas.


const { data: currentEpoch, error: errorCurrentEpoch } = await getRpcClient().blockchain.getEpochNumber()
const { data: latestBlock, error: errorCurrentEpoch } = await getRpcClient().blockchain.getLatestBlock()
if (errorCurrentEpoch)
return createError(errorCurrentEpoch)
const circulating = posSupplyAt(currentEpoch) * 1e5
const circulating = posSupplyAt(latestBlock.timestamp)

const ratio = staked / circulating
return { staked, circulating, ratio }
const stakedRatio = staked / circulating
return { staked, circulating, stakedRatio }
}, {
maxAge: import.meta.dev ? 0 : 60 * 60, // 60 minutes
})