Skip to content

Geyser APY

Nithin Krishna edited this page Jan 29, 2021 · 9 revisions

Calculating unlocks

Unlocks are linear. A geyser can have multiple unlock schedules overlaid on each other. To calculate the total AMPL unlocked in the next 'x' seconds you can use the following pseudocode.

function calculateAMPLUnlockedInNext(xSec){
  currentTimestampSec = Date.now()
  totalAMPLSharesUnlockedInXSec = 0
  for (i = 0; i < geyser.unlockScheduleCount; i++) {
    schedule = geyser.unlockSchedules[i]
    scheduleSecRemaining = max(schedule.endAtSec - currentTimestampSec, 0)
    calcTime = min(scheduleSecRemaining, xSec)
    totalAMPLSharesUnlockedInXSec += calcTime/schedule.durationSec * (schedule.initialLockedShares)
  }

  totalAMPLUnlockedInXSec = (totalAMPLSharesUnlockedInXSec / geyser.totalLockedShares) * geyser.totalLocked
  return totalAMPLUnlockedInXSec
}

Pool Apy

The APY estimate for the entire pool.

periodSec = geyser.bonusPeriodSec
          = 2592000 # 30 day bonus

N = number of periods 
  = (365*24*3600)/periodSec

inflowVal = geyser.totalLocked * LP_token_price
outflowVal = calculateAMPLUnlockedInNext(periodSec) * AMPL_price

i = yearly interest rate 
  = outflowVal/inflowVal * N 

APY = (1 + i / N ) ** N – 1
APY = (1 + outflowVal/inflowVal) ** N - 1

User Apy

The current APY for a user with a deposit.

periodSec = min(geyser.bonusPeriodSec, programTimeRemaining)
N = (365*24*3600)/periodSec

inflowVal = geyser.totalStakedFor(user) * LP_token_price

userStakingShares = (geyser.totalStakedFor(user) * geyser.totalStakingShares) / geyser.totalStaked
userTokenSecondsAfterT = geyser.userStakingShareSeconds + (userStakingShares * periodSec)
totalTokenSecondsAfterT = geyser.totalStakingShareSeconds + (geyser.totalStakingShares * periodSec)
userShareAfterT = userTokenSecondsAfterT / totalTokenSecondsAfterT
userDripAfterT = calculateAMPLUnlockedInNext(periodSec) * userShareAfterT
outflowVal = userDripAfterT * AMPL_price

APY = (1 + outflowVal/inflowVal) ** N - 1
Clone this wiki locally