Skip to content

Commit

Permalink
oracle: apply oracle reward contribution for probono validators (#205)
Browse files Browse the repository at this point in the history
  • Loading branch information
uhyunpark authored Aug 16, 2024
1 parent a84b183 commit bb57705
Show file tree
Hide file tree
Showing 4 changed files with 47 additions and 29 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -251,11 +251,11 @@ replace (
// use cosmos fork of keyring
github.com/99designs/keyring => github.com/cosmos/keyring v1.2.0
// use Settlus flavored Cosmos-SDK https://github.com/settlus/cosmos-sdk/releases
github.com/cosmos/cosmos-sdk => github.com/settlus/cosmos-sdk v0.47.12-settlus.2
github.com/cosmos/cosmos-sdk => github.com/settlus/cosmos-sdk v0.47.12-settlus.3
// use Evmos geth fork
github.com/ethereum/go-ethereum => github.com/evmos/go-ethereum v1.10.26-evmos-rc4
// use Settlus flavored Evmos
github.com/evmos/evmos/v19 => github.com/settlus/evmos/v19 v19.0.0-settlus.3.rc
github.com/evmos/evmos/v19 => github.com/settlus/evmos/v19 v19.0.0-settlus.3
// Security Advisory https://github.com/advisories/GHSA-h395-qcrw-5vmq
github.com/gin-gonic/gin => github.com/gin-gonic/gin v1.9.1
// use cosmos flavored protobufs
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -1213,10 +1213,10 @@ github.com/segmentio/fasthash v1.0.3/go.mod h1:waKX8l2N8yckOgmSsXJi7x1ZfdKZ4x7KR
github.com/segmentio/kafka-go v0.1.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/segmentio/kafka-go v0.2.0/go.mod h1:X6itGqS9L4jDletMsxZ7Dz+JFWxM6JHfPOCvTvk+EJo=
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
github.com/settlus/cosmos-sdk v0.47.12-settlus.2 h1:ho5ED+o0UI3ITiEckNdlqxgIxE++tYU2CgwfBanbttA=
github.com/settlus/cosmos-sdk v0.47.12-settlus.2/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0=
github.com/settlus/evmos/v19 v19.0.0-settlus.3.rc h1:z9ctKKoVsTw18fhFLW+OTUqwA76gMK63f/1ECU8T0dY=
github.com/settlus/evmos/v19 v19.0.0-settlus.3.rc/go.mod h1:cH2IV7ZrZlp+2KfeExMvtlQe8sxOYt2cC4J3ZiiwJHU=
github.com/settlus/cosmos-sdk v0.47.12-settlus.3 h1:RINSLTQes1z/7xOVXeeQetW6Iojrw0GtgBSRS3diLjw=
github.com/settlus/cosmos-sdk v0.47.12-settlus.3/go.mod h1:ADjORYzUQqQv/FxDi0H0K5gW/rAk1CiDR3ZKsExfJV0=
github.com/settlus/evmos/v19 v19.0.0-settlus.3 h1:P5n6lCDofIf4c2Kg3uNdj0nYad+A0Or7AwrfXwfQizc=
github.com/settlus/evmos/v19 v19.0.0-settlus.3/go.mod h1:oxzKo9nicHfPnGDV+sItCvz6Hkv1QhTFtG1dplSGcSE=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible h1:Bn1aCHHRnjv4Bl16T8rcaFjYSrGrIZvpiGO6P3Q4GpU=
github.com/shirou/gopsutil v3.21.4-0.20210419000835-c7a38de76ee5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=
github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc=
Expand Down
25 changes: 15 additions & 10 deletions x/oracle/keeper/feeder.go
Original file line number Diff line number Diff line change
Expand Up @@ -287,7 +287,7 @@ func (k Keeper) RewardBallotWinners(ctx sdk.Context, validatorClaimMap map[strin
logger.Debug("RewardBallotWinner", "rewards", rewards)

var distributedReward sdk.Coins
var probonoReward sdk.Coins
var totalContribution sdk.DecCoins

for addr, voter := range validatorClaimMap {
// skip if the validator abstained or missed the vote
Expand All @@ -313,12 +313,15 @@ func (k Keeper) RewardBallotWinners(ctx sdk.Context, validatorClaimMap map[strin
}

if !rewardCoins.IsZero() {
if receiverVal.IsProbono() {
probonoReward = probonoReward.Add(rewardCoins...)
continue
}
k.DistributionKeeper.AllocateTokensToValidator(ctx, receiverVal, sdk.NewDecCoinsFromCoins(rewardCoins...))
distributedReward = distributedReward.Add(rewardCoins...)
probonoRate := receiverVal.GetProbonoRate()
probonoContribution := sdk.NewDecCoinsFromCoins(rewardCoins...).MulDecTruncate(probonoRate)
totalContribution = totalContribution.Add(probonoContribution...)

finalReward := sdk.NewDecCoinsFromCoins(rewardCoins...).Sub(probonoContribution)
finalRewardCoins, _ := finalReward.TruncateDecimal()

k.DistributionKeeper.AllocateTokensToValidator(ctx, receiverVal, finalReward)
distributedReward = distributedReward.Add(finalRewardCoins...)
} else {
logger.Debug(fmt.Sprintf("no reward %s(%s)",
receiverVal.GetMoniker(),
Expand All @@ -329,11 +332,13 @@ func (k Keeper) RewardBallotWinners(ctx sdk.Context, validatorClaimMap map[strin
}

feePool := k.DistributionKeeper.GetFeePool(ctx)
feePool.CommunityPool = feePool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(probonoReward...)...)
feePool.CommunityPool = feePool.CommunityPool.Add(totalContribution...)
k.DistributionKeeper.SetFeePool(ctx, feePool)

totalContributionCoins, _ := totalContribution.TruncateDecimal()

// Move both distributed reward and probono reward to distribution module
if err := k.BankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.distributionName, distributedReward.Add(probonoReward...)); err != nil {
// Move both distributed reward and contribution reward to distribution module
if err := k.BankKeeper.SendCoinsFromModuleToModule(ctx, types.ModuleName, k.distributionName, distributedReward.Add(totalContributionCoins...)); err != nil {
return fmt.Errorf("failed to move distributed reward to distribution module: %w", err)
}

Expand Down
39 changes: 26 additions & 13 deletions x/oracle/keeper/keeper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,10 @@ func (suite *OracleTestSuite) TestKeeper_RewardBallotWinners_WithProbono() {
vcm map[string]types.Claim
totalCoin sdk.Coins
rewardMap map[string]sdk.DecCoins
probonoIndex []int
probonoMap map[int]sdk.Dec
}{
{
name: "Probono validators send rewards to community pool, normal validators get rewards as usual",
name: "Probono validators send rewards to community pool with their probono rate, normal validators get rewards",
vcm: map[string]types.Claim{
s.validators[0].GetOperator().String(): {
Weight: 100,
Expand Down Expand Up @@ -440,7 +440,10 @@ func (suite *OracleTestSuite) TestKeeper_RewardBallotWinners_WithProbono() {
s.validators[2].GetOperator().String(): sdk.NewDecCoins(sdk.NewInt64DecCoin("asetl", 1000000)),
s.validators[3].GetOperator().String(): sdk.NewDecCoins(sdk.NewInt64DecCoin("asetl", 1000000)),
},
probonoIndex: []int{0, 1},
probonoMap: map[int]sdk.Dec{
0: sdk.NewDecFromIntWithPrec(sdk.NewInt(2), 1), // 20% probono
1: sdk.NewDecFromIntWithPrec(sdk.NewInt(1), 0), // 100% probono
},
},
{
name: "All probono validator, there's no normal validator",
Expand Down Expand Up @@ -473,7 +476,12 @@ func (suite *OracleTestSuite) TestKeeper_RewardBallotWinners_WithProbono() {
s.validators[2].GetOperator().String(): sdk.NewDecCoins(sdk.NewInt64DecCoin("asetl", 1000000)),
s.validators[3].GetOperator().String(): sdk.NewDecCoins(sdk.NewInt64DecCoin("asetl", 1000000)),
},
probonoIndex: []int{0, 1, 2, 3},
probonoMap: map[int]sdk.Dec{
0: sdk.NewDecFromIntWithPrec(sdk.NewInt(1), 0), // 100% probono
1: sdk.NewDecFromIntWithPrec(sdk.NewInt(1), 0), // 100% probono
2: sdk.NewDecFromIntWithPrec(sdk.NewInt(1), 0), // 100% probono
3: sdk.NewDecFromIntWithPrec(sdk.NewInt(1), 0), // 100% probono
},
},
}

Expand All @@ -488,30 +496,35 @@ func (suite *OracleTestSuite) TestKeeper_RewardBallotWinners_WithProbono() {
s.app.DistrKeeper.SetFeePool(s.ctx, disttypes.InitialFeePool())
s.Equal(s.app.DistrKeeper.GetFeePoolCommunityCoins(s.ctx).AmountOf("asetl"), sdk.ZeroDec())

for _, idx := range tt.probonoIndex {
for idx, rate := range tt.probonoMap {
s.validators[idx].Probono = true
s.validators[idx].Commission = stakingtypes.NewCommission(
rate,
sdk.NewDecWithPrec(1, 0),
sdk.NewDecWithPrec(0, 0),
)
s.validators[idx] = stakingkeeper.TestingUpdateValidator(s.app.StakingKeeper, s.ctx, s.validators[idx], true)
}

probonoRewards := sdk.ZeroDec()
var probonoRewards sdk.DecCoins

err = s.app.OracleKeeper.RewardBallotWinners(s.ctx, tt.vcm)
s.NoError(err)

for _, validator := range s.validators {
if validator.IsProbono() {
probonoRewards = probonoRewards.Add(tt.rewardMap[validator.GetOperator().String()].AmountOf("asetl"))
validator.Probono = false
continue
}
contribution := tt.rewardMap[validator.GetOperator().String()].MulDec(validator.GetProbonoRate())

probonoRewards = probonoRewards.Add(contribution...)

rewards := s.app.DistrKeeper.GetValidatorCurrentRewards(s.ctx, validator.GetOperator())
s.Equal(tt.rewardMap[validator.GetOperator().String()].AmountOf("asetl"), rewards.Rewards.AmountOf("asetl"))
s.Equal(tt.rewardMap[validator.GetOperator().String()].Sub(contribution).AmountOf("asetl"), rewards.Rewards.AmountOf("asetl"))

s.app.DistrKeeper.DeleteValidatorCurrentRewards(s.ctx, validator.GetOperator())
}

// check community pool
actualCommunityAmount := s.app.DistrKeeper.GetFeePoolCommunityCoins(s.ctx).AmountOf("asetl")
s.Equal(probonoRewards, actualCommunityAmount)
s.Equal(probonoRewards.AmountOf("asetl"), actualCommunityAmount)
s.app.DistrKeeper.SetFeePool(s.ctx, disttypes.InitialFeePool())
})
}
Expand Down

0 comments on commit bb57705

Please sign in to comment.