mirror of
https://github.com/IT4Change/gradido.git
synced 2026-01-14 17:04:32 +00:00
59 lines
1.5 KiB
TypeScript
59 lines
1.5 KiB
TypeScript
import Decimal from 'decimal.js-light'
|
|
import CONFIG from '../config'
|
|
import { Decay } from '../graphql/model/Decay'
|
|
|
|
// TODO: externalize all those definitions and functions into an external decay library
|
|
|
|
function decayFormula(value: Decimal, seconds: number): Decimal {
|
|
// TODO why do we need to convert this here to a stting to work properly?
|
|
return value.mul(
|
|
new Decimal('0.99999997803504048973201202316767079413460520837376').pow(seconds).toString(),
|
|
)
|
|
}
|
|
|
|
function calculateDecay(
|
|
amount: Decimal,
|
|
from: Date,
|
|
to: Date,
|
|
startBlock: Date = CONFIG.DECAY_START_TIME,
|
|
): Decay {
|
|
const fromMs = from.getTime()
|
|
const toMs = to.getTime()
|
|
const startBlockMs = startBlock.getTime()
|
|
|
|
if (toMs < fromMs) {
|
|
throw new Error('to < from, reverse decay calculation is invalid')
|
|
}
|
|
|
|
// Initialize with no decay
|
|
const decay: Decay = {
|
|
balance: amount,
|
|
decay: new Decimal(0),
|
|
start: null,
|
|
end: null,
|
|
duration: null,
|
|
}
|
|
|
|
// decay started after end date; no decay
|
|
if (startBlockMs > toMs) {
|
|
return decay
|
|
}
|
|
// decay started before start date; decay for full duration
|
|
if (startBlockMs < fromMs) {
|
|
decay.start = from
|
|
decay.duration = (toMs - fromMs) / 1000
|
|
}
|
|
// decay started between start and end date; decay from decay start till end date
|
|
else {
|
|
decay.start = startBlock
|
|
decay.duration = (toMs - startBlockMs) / 1000
|
|
}
|
|
|
|
decay.end = to
|
|
decay.balance = decayFormula(amount, decay.duration)
|
|
decay.decay = decay.balance.minus(amount)
|
|
return decay
|
|
}
|
|
|
|
export { decayFormula, calculateDecay }
|