# Compounded Dynamic Staking

$\text{Anonymous}\\ \text{Blockchain Architect of OpenPad}$

OpenPad employs an auto-compounded vault mechanism for $OPN staking, compounding investor stakes to generate exponential returns and calculate the token sale allocations based on the compounded capital. An auto-compound mechanism is used to reinvest rewards generated from the staking pool into the same staking pool, creating a compound effect.

A time-based mathematical formula is used to track the rewards and staking balances of every staker in the vault and the formula is updated according to the last update time and current time after every staking amount changing transaction.

The parameters are as follows:

(can be any user)**LastUpdateTime**

(total staked amount)**TotalSupply****UserBalance**

(total reward added to the user so far)**Rewards[.]**

(Total rewards paid to all users so far)**PaidReward[.]**

(reward to pay in return for a single token per second)**RewardRate**

Let’s imagine

*tokens. The***user A staking 100 $OPN****updateRewards**

function is called before the staking action and the initial parameters are updated as follows.$rewardsPerTokenStored = 0 \text{ (Since totalSupply is zero initially)} \\lastUpdateTime=t_0$

Then, the reward parameters of user A,

**rewards[A] and userRewardPerTokenPaid[A]**

, are updated as follows.$rewards[A] = 0 \text{ (Since balance of A is 0 initially) } \\ userRewardPerTokenPaid[A] = rewardsPerTokenStored \text{ (0 in this case) }$

After updating these parameters, the algorithm continues with the accumulation of

**totalSupply and balances[A].**

$totalSupply=0+100=100 \\
balances[A]=0+100=100$

Now that we have initialized the first staking parameters and we have a non-zero

**totalSupply**

; let’s imagine a new **user B staking 200 tokens**assuming`t1`

is the current time.$rewardsPerTokenStored = 0 + (t_1-t_0) * \dfrac{rewardRate}{100 * totalSupply} \\
lastUpdateTime=t_1 \\$

Then, the reward parameters of user B,

**rewards[B] and userRewardPerTokenPaid[B], **

are updated as follows. $rewards[B]= 0 \text{ (Since balance of B is 0 initially)} \\
userRewardPerTokenPaid[B] = rewardsPerTokenStored = \dfrac{(t_1-t_0) * rewardRate}{100 * totalSupply}$

After updating these parameters, the algorithm continues with the accumulation of

**totalSupply and balances[B].**

$totalSupply=100+200=300 \\
balances[B]=0+200=200$

Now, let's imagine that another user joins the staking pool, say user C, staking 300 $OPN tokens.

**rewardsPerTokenStored and lastUpdateTime**

is updated as follows.$rewardsPerTokenStored= (t_1-t_0) * \dfrac{rewardRate}{100}+ (t_2-t_1) * \dfrac{rewardRate}{300} \\
lastUpdateTime=t_2$

Then, the reward parameters of user C,

**rewards[C] and userRewardPerTokenPaid[C],**

are updated as follows.$\\
rewards[C]=0 \text{ (Since balance of B is 0 initially)} \\ userRewardPerTokenPaid[C]=rewardsPerTokenStored =\dfrac{(t_1-t_0) * rewardRate}{100} * \dfrac{(t_2-t_1) * rewardRate}{300}$

After updating these parameters, the algorithm continues with the accumulation of

**totalSupply and balances[C].**

$totalSupply=300+300=600 \\
balances[C]=0+300=300$

Now the essential part of the algorithm comes to play. What if user

**B wants to claim their rewards**? How does the algorithm calculate how much B has earned since they staked after A but before C?**getReward**

function also triggers the **updateRewards**

function so the parameters are updated.$rewardsPerTokenStored= (t_1-t_0) * \dfrac{rewardRate}{100} + (t_2-t_1) * \dfrac{rewardRate}{300} + (t_3-t_2) * \dfrac{rewardRate}{600} \\ lastUpdateTime=t3$

Then, the reward parameters of user B,

**rewards[B]**

, are updated as follows.$rewards[B]=balances[B]* (rewardsPerTokenStored-userRewardPerTokenPaid[B])+rewards[B] \\ rewards[B]=200* ((t_1-t_0)* \dfrac{rewardRate}{100}+ (t_2-t_1)* \dfrac{rewardRate}{300}+ (t_3-t_2) * \dfrac{rewardRate}{600}- (\dfrac{(t_1 - t_0) *rewardRate}{100 * totalSupply})) \\ rewards[B]=200* ((t_2-t_1) * \dfrac{rewardRate}{300} + (t_3-t_2) * \dfrac{rewardRate}{600}\\$

Finally,

**userRewardPerTokenPaid[B]**

is calculated as follows.$userRewardPerTokenPaid[B]= \dfrac{(t_1-t_0) * rewardRate}{100} + \dfrac{(t_2-t_1) * rewardRate}{300} + \dfrac{(t_3-t_2) * rewardRate}{600}$

Now the necessary updates have been completed and user B is ready to claim their rewards which are stored in the

**rewards[B]**

mapping that we just updated. The reward is sent to the user and is reset to 0 until they claim again at a later time. As seen from the calculations, the reward is calculated so that it does not account for the time period where B has not staked (There was only user A) but accounts for the time periods where there is**<A, B>**

and **<A, B, C**

> separately. This algorithm handles every user’s rewards in the same way.To understand auto-compound strategy in $OPN staking, the concept of

**APR (Annual Percentage Rate)**

and **APY (Annual Percentage Yield)**

should be understood. Simply, **APR**

is simple and **APY**

is compound interest, reflecting the interest you make in your interest.

$APR = (\dfrac{(\dfrac{InterestReturn}{Principal})}{n} * 365) *100$

where

**InterestReturn**

is the total interest paid over the life of the staking, **principal**

is the total deposit, and **n**

is the number of days in the total reward period. Hence, there is no rebasing or reinvesting included whereas, in the APY calculation, interest on the earned interest (reinvesting effect) is also considered.$APY = (1 + \dfrac{APR}{n})^N - 1$

where

**N**

is the compounding frequency (e.g., daily, weekly, monthly, quarterly, etc.) With every rebase, the returned interest reward is added to the stakers' balance automatically resulting in a higher compound rate in the next period.

To compare

**APR**

and **APY**

, let's imagine that $OPN staking offers 100% **APR**

at a certain timeframe, and imagine this **APR**

continues to remain the same for over one year. Then, let **N = 365, **

i.e., if compounding frequency is daily, and let **Principal = $10,000**

then **APY, TotalInterest**

and**FutureValue**

will be$APY = (1 + \dfrac{100}{365})^{365} - 1 = 171.4567 \%$

Hence, there is a

**71.4567%**

interest rate difference between **APR**

and **APY.**

$\\ Future Value = \$27,145.67 \\ Total Interest=FutureValue -Principal = 17.145,67$

Daily compound interest accumulated

**FutureValue**

of the user to **27,145.67**

which will be **20,000**

if compound interest wouldn't be considered, creating a **7,145.67**

extra interest. To compare the compound effect of the $OPN auto-compound staking pool with the simple staking pools, here is the graph representing the accumulated $OPN amount over time; the difference between auto-compounded capital and simple capital is increasing over time, reaching `7,145.67 `

at the end of the first year and **43688.76**

at the end of the second year.The dark filled area represents the difference between $OPN capitals over time

Note that staking/vault fees are not considered here; however, the calculation of the APR can be computed considering network fees as follows.

$Realized APR= APR * (1 - F_P) \\ RealizedAPY = (1 + \dfrac{APR * (1 - F_P)}{n})^N - 1$

where

**RealizedAPR**

is the actual **APR**

rate after subtracting protocol fees **FP.**

Last modified 1yr ago