mirror of
https://github.com/IT4Change/gradido.git
synced 2025-12-13 07:45:54 +00:00
65 lines
1.8 KiB
TypeScript
65 lines
1.8 KiB
TypeScript
import { Decimal } from 'decimal.js-light'
|
|
import CONFIG from '@/config'
|
|
import { Decay } from '@model/Decay'
|
|
import LogError from '@/server/LogError'
|
|
|
|
// 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 LogError('calculateDecay: to < from, reverse decay calculation is invalid')
|
|
}
|
|
|
|
// Initialize with no decay
|
|
const decay: Decay = {
|
|
balance: amount,
|
|
decay: new Decimal(0),
|
|
roundedDecay: 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)
|
|
decay.roundedDecay = amount
|
|
.toDecimalPlaces(2, Decimal.ROUND_DOWN)
|
|
.minus(decay.balance.toDecimalPlaces(2, Decimal.ROUND_DOWN).toString())
|
|
.mul(-1)
|
|
return decay
|
|
}
|
|
|
|
export { decayFormula, calculateDecay }
|