/
indicator.go
113 lines (90 loc) · 3.42 KB
/
indicator.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package keeper
import (
core "github.com/terra-project/core/types"
sdk "github.com/cosmos/cosmos-sdk/types"
)
//
// Computes important economic indicators for the stability of Terra currencies.
//
// Three important concepts:
// - MR: Fees + Seigniorage for a given epoch sums to Mining Rewards
// - SR: Computes the Seigniorage Reward
// - TR: Computes the Tax Reward
// - TSL: Total Staked Luna
// - TRL: Computes the Tax Reward per unit Luna (TR/TSL)
// alignCoins align the coins to the given denom through the market swap
func (k Keeper) alignCoins(ctx sdk.Context, coins sdk.DecCoins, denom string) (alignedAmt sdk.Dec) {
alignedAmt = sdk.ZeroDec()
for _, coinReward := range coins {
if coinReward.Denom != denom {
swappedReward, err := k.marketKeeper.ComputeInternalSwap(ctx, coinReward, denom)
if err != nil {
continue
}
alignedAmt = alignedAmt.Add(swappedReward.Amount)
} else {
alignedAmt = alignedAmt.Add(coinReward.Amount)
}
}
return alignedAmt
}
// UpdateIndicators updates interal indicators
func (k Keeper) UpdateIndicators(ctx sdk.Context) {
epoch := core.GetEpoch(ctx)
// Compute Total Staked Luna (TSL)
totalStakedLuna := k.stakingKeeper.TotalBondedTokens(ctx)
k.SetTSL(ctx, epoch, totalStakedLuna)
// Compute Tax Rewards (TR)
taxRewards := sdk.NewDecCoins(k.PeekEpochTaxProceeds(ctx))
TR := k.alignCoins(ctx, taxRewards, core.MicroSDRDenom)
k.SetTR(ctx, epoch, TR)
// Reset tax proceeds after computing TRL for the next epoch
k.SetEpochTaxProceeds(ctx, sdk.Coins{})
// Compute Seigniorage Rewards (SR)
seigniorage := k.PeekEpochSeigniorage(ctx)
seigniorageRewardsAmt := k.GetRewardWeight(ctx).MulInt(seigniorage)
seigniorageRewards := sdk.DecCoins{sdk.NewDecCoinFromDec(core.MicroLunaDenom, seigniorageRewardsAmt)}
SR := k.alignCoins(ctx, seigniorageRewards, core.MicroSDRDenom)
k.SetSR(ctx, epoch, SR)
}
// TRL returns Tax Rewards per Luna for the epoch
func TRL(ctx sdk.Context, epoch int64, k Keeper) sdk.Dec {
return k.GetTR(ctx, epoch).QuoInt(k.GetTSL(ctx, epoch))
}
// SR returns Seigniorage Rewards for the epoch
func SR(ctx sdk.Context, epoch int64, k Keeper) sdk.Dec {
return k.GetSR(ctx, epoch)
}
// MR returns Mining Rewards = Seigniorage Rewards + Tax Rates for the epoch
func MR(ctx sdk.Context, epoch int64, k Keeper) sdk.Dec {
return k.GetTR(ctx, epoch).Add(k.GetSR(ctx, epoch))
}
// sumIndicator returns the sum of the indicator over several epochs.
// If current epoch < epochs, we return the best we can and return sumIndicator(currentEpoch)
func (k Keeper) sumIndicator(ctx sdk.Context, epochs int64,
indicator func(ctx sdk.Context, epoch int64, k Keeper) sdk.Dec) sdk.Dec {
sum := sdk.ZeroDec()
curEpoch := core.GetEpoch(ctx)
for i := curEpoch; i >= 0 && i > (curEpoch-epochs); i-- {
val := indicator(ctx, i, k)
sum = sum.Add(val)
}
return sum
}
// rollingAverageIndicator returns the rolling average of the indicator over several epochs.
// If current epoch < epochs, we return the best we can and return rollingAverageIndicator(currentEpoch)
func (k Keeper) rollingAverageIndicator(ctx sdk.Context, epochs int64,
indicator func(ctx sdk.Context, epoch int64, k Keeper) sdk.Dec) sdk.Dec {
sum := sdk.ZeroDec()
curEpoch := core.GetEpoch(ctx)
var i int64
for i = curEpoch; i >= 0 && i > (curEpoch-epochs); i-- {
val := indicator(ctx, i, k)
sum = sum.Add(val)
}
computedEpochs := curEpoch - i
if computedEpochs == 0 {
return sum
}
return sum.QuoInt64(computedEpochs)
}