Skip to content

Commit fe7454a

Browse files
Merge pull request #317 from terra-money/patch/fix-reward
fix: reward calculation for different types of token
2 parents 621d2fb + 2943e54 commit fe7454a

File tree

9 files changed

+531
-128
lines changed

9 files changed

+531
-128
lines changed

docs/proto/proto-docs.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@
137137
| ----- | ---- | ----- | ----------- |
138138
| `denom` | [string](#string) | | |
139139
| `index` | [string](#string) | | |
140+
| `alliance` | [string](#string) | | |
140141

141142

142143

proto/alliance/alliance/params.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,5 @@ message RewardHistory {
3434
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
3535
(gogoproto.nullable) = false
3636
];
37+
string alliance = 3;
3738
}

x/alliance/keeper/asset.go

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -28,15 +28,6 @@ func (k Keeper) InitializeAllianceAssets(ctx context.Context, assets []*types.Al
2828
continue
2929
}
3030
asset.IsInitialized = true
31-
err = k.IterateAllianceValidatorInfo(ctx, func(valAddr sdk.ValAddress, info types.AllianceValidatorInfo) bool {
32-
if err = k.CreateInitialRewardWeightChangeSnapshot(ctx, asset.Denom, valAddr, info); err != nil {
33-
return true
34-
}
35-
return false
36-
})
37-
if err != nil {
38-
return err
39-
}
4031
if err = k.SetAsset(ctx, *asset); err != nil {
4132
return err
4233
}
@@ -387,15 +378,6 @@ func (k Keeper) SetRewardWeightChangeSnapshot(ctx context.Context, asset types.A
387378
return k.setRewardWeightChangeSnapshot(ctx, asset.Denom, valAddr, uint64(sdkCtx.BlockHeight()), snapshot)
388379
}
389380

390-
func (k Keeper) CreateInitialRewardWeightChangeSnapshot(ctx context.Context, denom string, valAddr sdk.ValAddress, info types.AllianceValidatorInfo) error {
391-
snapshot := types.RewardWeightChangeSnapshot{
392-
PrevRewardWeight: cmath.LegacyZeroDec(),
393-
RewardHistories: info.GlobalRewardHistory,
394-
}
395-
sdkCtx := sdk.UnwrapSDKContext(ctx)
396-
return k.setRewardWeightChangeSnapshot(ctx, denom, valAddr, uint64(sdkCtx.BlockHeight()), snapshot)
397-
}
398-
399381
func (k Keeper) setRewardWeightChangeSnapshot(ctx context.Context, denom string, valAddr sdk.ValAddress, height uint64, snapshot types.RewardWeightChangeSnapshot) error {
400382
key := types.GetRewardWeightChangeSnapshotKey(denom, valAddr, height)
401383
store := k.storeService.OpenKVStore(ctx)

x/alliance/keeper/reward.go

Lines changed: 39 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -103,9 +103,9 @@ func (k Keeper) ClaimDelegationRewards(
103103
// It takes past reward_rate changes into account by using the RewardRateChangeSnapshot entry
104104
func (k Keeper) CalculateDelegationRewards(ctx context.Context, delegation types.Delegation, val types.AllianceValidator, asset types.AllianceAsset) (sdk.Coins, types.RewardHistories, error) {
105105
totalRewards := sdk.NewCoins()
106-
currentRewardHistory := types.NewRewardHistories(val.GlobalRewardHistory)
107-
delegationRewardHistories := types.NewRewardHistories(delegation.RewardHistory)
108106

107+
currentRewardHistory := types.NewRewardHistories(val.GlobalRewardHistory).GetIndexByAlliance(asset.Denom)
108+
delegationRewardHistories := types.NewRewardHistories(delegation.RewardHistory).GetIndexByAlliance(asset.Denom)
109109
valAddr, err := sdk.ValAddressFromBech32(val.OperatorAddress)
110110
if err != nil {
111111
return nil, nil, err
@@ -136,15 +136,22 @@ func accumulateRewards(latestRewardHistories types.RewardHistories, rewardHistor
136136

137137
delegationTokens := math.LegacyNewDecFromInt(types.GetDelegationTokens(delegation, validator, asset).Amount)
138138
for _, history := range latestRewardHistories {
139-
rewardHistory, found := rewardHistories.GetIndexByDenom(history.Denom)
139+
rewardHistory, found := rewardHistories.GetIndexByDenom(history.Denom, history.Alliance)
140140
if !found {
141141
rewardHistory.Denom = history.Denom
142142
rewardHistory.Index = math.LegacyZeroDec()
143+
rewardHistory.Alliance = history.Alliance
143144
}
144145
if rewardHistory.Index.GTE(history.Index) {
145146
continue
146147
}
147-
claimWeight := delegationTokens.Mul(rewardWeight)
148+
var claimWeight math.LegacyDec
149+
// Handle legacy reward history that does not have a specific alliance
150+
if rewardHistory.Alliance == "" {
151+
claimWeight = delegationTokens.Mul(rewardWeight)
152+
} else {
153+
claimWeight = delegationTokens
154+
}
148155
totalClaimable := (history.Index.Sub(rewardHistory.Index)).Mul(claimWeight)
149156
rewardHistory.Index = history.Index
150157
rewards = rewards.Add(sdk.NewCoin(history.Denom, totalClaimable.TruncateInt()))
@@ -163,22 +170,35 @@ func (k Keeper) AddAssetsToRewardPool(ctx context.Context, from sdk.AccAddress,
163170
if len(val.TotalDelegatorShares) == 0 {
164171
return nil
165172
}
173+
alliances := k.GetAllAssets(ctx)
166174

167-
totalAssetWeight := k.totalAssetWeight(ctx, val)
168-
if totalAssetWeight.IsZero() {
169-
// Do nothing since there are no assets to distribute rewards to
170-
return nil
175+
// Get total reward weight to normalize weights
176+
totalRewardWeight := math.LegacyZeroDec()
177+
for _, asset := range alliances {
178+
if shouldSkipRewardsToAsset(ctx, *asset, val) {
179+
continue
180+
}
181+
totalRewardWeight = totalRewardWeight.Add(asset.RewardWeight)
171182
}
172183

173-
for _, c := range coins {
174-
rewardHistory, found := rewardHistories.GetIndexByDenom(c.Denom)
175-
if !found {
176-
rewardHistories = append(rewardHistories, types.RewardHistory{
177-
Denom: c.Denom,
178-
Index: math.LegacyNewDecFromInt(c.Amount).Quo(totalAssetWeight),
179-
})
180-
} else {
181-
rewardHistory.Index = rewardHistory.Index.Add(math.LegacyNewDecFromInt(c.Amount).Quo(totalAssetWeight))
184+
for _, asset := range alliances {
185+
if shouldSkipRewardsToAsset(ctx, *asset, val) {
186+
continue
187+
}
188+
normalizedWeight := asset.RewardWeight.Quo(totalRewardWeight)
189+
for _, c := range coins {
190+
rewardHistory, found := rewardHistories.GetIndexByDenom(c.Denom, asset.Denom)
191+
totalTokens := val.TotalTokensWithAsset(*asset)
192+
difference := math.LegacyNewDecFromInt(c.Amount).Mul(normalizedWeight).Quo(totalTokens)
193+
if !found {
194+
rewardHistories = append(rewardHistories, types.RewardHistory{
195+
Denom: c.Denom,
196+
Alliance: asset.Denom,
197+
Index: difference,
198+
})
199+
} else {
200+
rewardHistory.Index = rewardHistory.Index.Add(difference)
201+
}
182202
}
183203
}
184204

@@ -189,19 +209,7 @@ func (k Keeper) AddAssetsToRewardPool(ctx context.Context, from sdk.AccAddress,
189209
return k.bankKeeper.SendCoinsFromAccountToModule(ctx, from, types.RewardsPoolName, coins)
190210
}
191211

192-
func (k Keeper) totalAssetWeight(ctx context.Context, val types.AllianceValidator) math.LegacyDec {
193-
total := math.LegacyZeroDec()
212+
func shouldSkipRewardsToAsset(ctx context.Context, asset types.AllianceAsset, val types.AllianceValidator) bool {
194213
sdkCtx := sdk.UnwrapSDKContext(ctx)
195-
for _, token := range val.TotalDelegatorShares {
196-
asset, found := k.GetAssetByDenom(ctx, token.Denom)
197-
if !found {
198-
continue
199-
}
200-
if !asset.RewardsStarted(sdkCtx.BlockTime()) {
201-
continue
202-
}
203-
totalValTokens := val.TotalTokensWithAsset(asset)
204-
total = total.Add(asset.RewardWeight.Mul(totalValTokens))
205-
}
206-
return total
214+
return asset.TotalTokens.IsZero() || !asset.RewardsStarted(sdkCtx.BlockTime()) || val.TotalTokensWithAsset(asset).IsZero()
207215
}

x/alliance/keeper/tests/grpc_query_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ func TestClaimQueryReward(t *testing.T) {
324324
Rewards: []sdk.Coin{
325325
{
326326
Denom: ULunaAlliance,
327-
Amount: math.NewInt(32666),
327+
Amount: math.NewInt(32665),
328328
},
329329
},
330330
}, queryDelegation)

0 commit comments

Comments
 (0)