Skip to content

Commit

Permalink
Merge pull request #317 from terra-money/patch/fix-reward
Browse files Browse the repository at this point in the history
fix: reward calculation for different types of token
  • Loading branch information
javiersuweijie authored Feb 28, 2024
2 parents 621d2fb + 2943e54 commit fe7454a
Show file tree
Hide file tree
Showing 9 changed files with 531 additions and 128 deletions.
1 change: 1 addition & 0 deletions docs/proto/proto-docs.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,7 @@
| ----- | ---- | ----- | ----------- |
| `denom` | [string](#string) | | |
| `index` | [string](#string) | | |
| `alliance` | [string](#string) | | |



Expand Down
1 change: 1 addition & 0 deletions proto/alliance/alliance/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,5 @@ message RewardHistory {
(gogoproto.customtype) = "cosmossdk.io/math.LegacyDec",
(gogoproto.nullable) = false
];
string alliance = 3;
}
18 changes: 0 additions & 18 deletions x/alliance/keeper/asset.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,6 @@ func (k Keeper) InitializeAllianceAssets(ctx context.Context, assets []*types.Al
continue
}
asset.IsInitialized = true
err = k.IterateAllianceValidatorInfo(ctx, func(valAddr sdk.ValAddress, info types.AllianceValidatorInfo) bool {
if err = k.CreateInitialRewardWeightChangeSnapshot(ctx, asset.Denom, valAddr, info); err != nil {
return true
}
return false
})
if err != nil {
return err
}
if err = k.SetAsset(ctx, *asset); err != nil {
return err
}
Expand Down Expand Up @@ -387,15 +378,6 @@ func (k Keeper) SetRewardWeightChangeSnapshot(ctx context.Context, asset types.A
return k.setRewardWeightChangeSnapshot(ctx, asset.Denom, valAddr, uint64(sdkCtx.BlockHeight()), snapshot)
}

func (k Keeper) CreateInitialRewardWeightChangeSnapshot(ctx context.Context, denom string, valAddr sdk.ValAddress, info types.AllianceValidatorInfo) error {
snapshot := types.RewardWeightChangeSnapshot{
PrevRewardWeight: cmath.LegacyZeroDec(),
RewardHistories: info.GlobalRewardHistory,
}
sdkCtx := sdk.UnwrapSDKContext(ctx)
return k.setRewardWeightChangeSnapshot(ctx, denom, valAddr, uint64(sdkCtx.BlockHeight()), snapshot)
}

func (k Keeper) setRewardWeightChangeSnapshot(ctx context.Context, denom string, valAddr sdk.ValAddress, height uint64, snapshot types.RewardWeightChangeSnapshot) error {
key := types.GetRewardWeightChangeSnapshotKey(denom, valAddr, height)
store := k.storeService.OpenKVStore(ctx)
Expand Down
70 changes: 39 additions & 31 deletions x/alliance/keeper/reward.go
Original file line number Diff line number Diff line change
Expand Up @@ -103,9 +103,9 @@ func (k Keeper) ClaimDelegationRewards(
// It takes past reward_rate changes into account by using the RewardRateChangeSnapshot entry
func (k Keeper) CalculateDelegationRewards(ctx context.Context, delegation types.Delegation, val types.AllianceValidator, asset types.AllianceAsset) (sdk.Coins, types.RewardHistories, error) {
totalRewards := sdk.NewCoins()
currentRewardHistory := types.NewRewardHistories(val.GlobalRewardHistory)
delegationRewardHistories := types.NewRewardHistories(delegation.RewardHistory)

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

delegationTokens := math.LegacyNewDecFromInt(types.GetDelegationTokens(delegation, validator, asset).Amount)
for _, history := range latestRewardHistories {
rewardHistory, found := rewardHistories.GetIndexByDenom(history.Denom)
rewardHistory, found := rewardHistories.GetIndexByDenom(history.Denom, history.Alliance)
if !found {
rewardHistory.Denom = history.Denom
rewardHistory.Index = math.LegacyZeroDec()
rewardHistory.Alliance = history.Alliance
}
if rewardHistory.Index.GTE(history.Index) {
continue
}
claimWeight := delegationTokens.Mul(rewardWeight)
var claimWeight math.LegacyDec
// Handle legacy reward history that does not have a specific alliance
if rewardHistory.Alliance == "" {
claimWeight = delegationTokens.Mul(rewardWeight)
} else {
claimWeight = delegationTokens
}
totalClaimable := (history.Index.Sub(rewardHistory.Index)).Mul(claimWeight)
rewardHistory.Index = history.Index
rewards = rewards.Add(sdk.NewCoin(history.Denom, totalClaimable.TruncateInt()))
Expand All @@ -163,22 +170,35 @@ func (k Keeper) AddAssetsToRewardPool(ctx context.Context, from sdk.AccAddress,
if len(val.TotalDelegatorShares) == 0 {
return nil
}
alliances := k.GetAllAssets(ctx)

totalAssetWeight := k.totalAssetWeight(ctx, val)
if totalAssetWeight.IsZero() {
// Do nothing since there are no assets to distribute rewards to
return nil
// Get total reward weight to normalize weights
totalRewardWeight := math.LegacyZeroDec()
for _, asset := range alliances {
if shouldSkipRewardsToAsset(ctx, *asset, val) {
continue
}
totalRewardWeight = totalRewardWeight.Add(asset.RewardWeight)
}

for _, c := range coins {
rewardHistory, found := rewardHistories.GetIndexByDenom(c.Denom)
if !found {
rewardHistories = append(rewardHistories, types.RewardHistory{
Denom: c.Denom,
Index: math.LegacyNewDecFromInt(c.Amount).Quo(totalAssetWeight),
})
} else {
rewardHistory.Index = rewardHistory.Index.Add(math.LegacyNewDecFromInt(c.Amount).Quo(totalAssetWeight))
for _, asset := range alliances {
if shouldSkipRewardsToAsset(ctx, *asset, val) {
continue
}
normalizedWeight := asset.RewardWeight.Quo(totalRewardWeight)
for _, c := range coins {
rewardHistory, found := rewardHistories.GetIndexByDenom(c.Denom, asset.Denom)
totalTokens := val.TotalTokensWithAsset(*asset)
difference := math.LegacyNewDecFromInt(c.Amount).Mul(normalizedWeight).Quo(totalTokens)
if !found {
rewardHistories = append(rewardHistories, types.RewardHistory{
Denom: c.Denom,
Alliance: asset.Denom,
Index: difference,
})
} else {
rewardHistory.Index = rewardHistory.Index.Add(difference)
}
}
}

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

func (k Keeper) totalAssetWeight(ctx context.Context, val types.AllianceValidator) math.LegacyDec {
total := math.LegacyZeroDec()
func shouldSkipRewardsToAsset(ctx context.Context, asset types.AllianceAsset, val types.AllianceValidator) bool {
sdkCtx := sdk.UnwrapSDKContext(ctx)
for _, token := range val.TotalDelegatorShares {
asset, found := k.GetAssetByDenom(ctx, token.Denom)
if !found {
continue
}
if !asset.RewardsStarted(sdkCtx.BlockTime()) {
continue
}
totalValTokens := val.TotalTokensWithAsset(asset)
total = total.Add(asset.RewardWeight.Mul(totalValTokens))
}
return total
return asset.TotalTokens.IsZero() || !asset.RewardsStarted(sdkCtx.BlockTime()) || val.TotalTokensWithAsset(asset).IsZero()
}
2 changes: 1 addition & 1 deletion x/alliance/keeper/tests/grpc_query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ func TestClaimQueryReward(t *testing.T) {
Rewards: []sdk.Coin{
{
Denom: ULunaAlliance,
Amount: math.NewInt(32666),
Amount: math.NewInt(32665),
},
},
}, queryDelegation)
Expand Down
Loading

0 comments on commit fe7454a

Please sign in to comment.