diff --git a/app/app.go b/app/app.go index 1645bcb21..d4b01c7c4 100644 --- a/app/app.go +++ b/app/app.go @@ -158,7 +158,9 @@ func NewTerraApp(logger log.Logger, db dbm.DB, traceStore io.Writer, loadLatest // add keepers app.accountKeeper = auth.NewAccountKeeper(app.cdc, keys[auth.StoreKey], authSubspace, auth.ProtoBaseAccount) - app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace, app.ModuleAccountAddrs()) + sendBlackListAddrs := app.ModuleAccountAddrs() + delete(sendBlackListAddrs, oracle.ModuleName) + app.bankKeeper = bank.NewBaseKeeper(app.accountKeeper, bankSubspace, bank.DefaultCodespace, sendBlackListAddrs) app.supplyKeeper = supply.NewKeeper(app.cdc, keys[supply.StoreKey], app.accountKeeper, app.bankKeeper, maccPerms) stakingKeeper := staking.NewKeeper(app.cdc, keys[staking.StoreKey], tkeys[staking.TStoreKey], app.supplyKeeper, stakingSubspace, staking.DefaultCodespace) diff --git a/x/oracle/abci.go b/x/oracle/abci.go index d96155f73..0aff9c309 100644 --- a/x/oracle/abci.go +++ b/x/oracle/abci.go @@ -21,7 +21,7 @@ func EndBlocker(ctx sdk.Context, k Keeper) { actives := k.GetActiveDenoms(ctx) votes := k.CollectVotes(ctx) - // Clear swap rates + // Clear prices for _, activeDenom := range actives { k.DeletePrice(ctx, activeDenom) } @@ -33,43 +33,51 @@ func EndBlocker(ctx sdk.Context, k Keeper) { return false }) + // Changes whitelist array to map for fast lookup + whitelistMap := make(map[string]bool) + for _, denom := range k.Whitelist(ctx) { + whitelistMap[denom] = true + } + // Iterate through votes and update prices; drop if not enough votes have been achieved. claimMap := make(map[string]types.Claim) for denom, ballot := range votes { - if ballotIsPassing(ctx, ballot, k) { - // Get weighted median prices, and faithful respondants - mod, ballotWinners, ballotLosers := tally(ctx, ballot, k) + // Check whitelist; if denom is not exists or exists but the ballot is not passed, then skip + if _, exists := whitelistMap[denom]; !exists || !ballotIsPassing(ctx, ballot, k) { + continue + } - for _, loser := range ballotLosers { - key := loser.String() - if _, exists := ballotAttendees[key]; exists { - ballotAttendees[key] = false // inproper vote - } - } + // Get weighted median prices, and faithful respondants + mod, ballotWinners, ballotLosers := tally(ctx, ballot, k) - // Collect claims of ballot winners - for _, winner := range ballotWinners { - key := winner.Recipient.String() - claim, exists := claimMap[key] - if exists { - claim.Weight += winner.Weight - claimMap[key] = claim - } else { - claimMap[key] = winner - } + for _, loser := range ballotLosers { + key := loser.String() + if _, exists := ballotAttendees[key]; exists { + ballotAttendees[key] = false // inproper vote } + } - // Set price to the store - k.SetLunaPrice(ctx, denom, mod) - - ctx.EventManager().EmitEvent( - sdk.NewEvent(types.EventTypePriceUpdate, - sdk.NewAttribute(types.AttributeKeyDenom, denom), - sdk.NewAttribute(types.AttributeKeyPrice, mod.String()), - ), - ) + // Collect claims of ballot winners + for _, winner := range ballotWinners { + key := winner.Recipient.String() + claim, exists := claimMap[key] + if exists { + claim.Weight += winner.Weight + claimMap[key] = claim + } else { + claimMap[key] = winner + } } + + // Set price to the store + k.SetLunaPrice(ctx, denom, mod) + ctx.EventManager().EmitEvent( + sdk.NewEvent(types.EventTypePriceUpdate, + sdk.NewAttribute(types.AttributeKeyDenom, denom), + sdk.NewAttribute(types.AttributeKeyPrice, mod.String()), + ), + ) } // Convert map to array diff --git a/x/oracle/abci_test.go b/x/oracle/abci_test.go index 6c11c4d01..481506e0e 100644 --- a/x/oracle/abci_test.go +++ b/x/oracle/abci_test.go @@ -307,7 +307,7 @@ func TestOracleRewardDistribution(t *testing.T) { EndBlocker(input.Ctx.WithBlockHeight(1), input.OracleKeeper) - expectedRewardAmt := input.OracleKeeper.RewardFraction(input.Ctx).MulInt(stakingAmt.MulRaw(50)).TruncateInt() + expectedRewardAmt := sdk.NewDecFromInt(stakingAmt.MulRaw(50)).MulInt64(input.OracleKeeper.VotePeriod(input.Ctx)).QuoInt64(input.OracleKeeper.RewardDistributionPeriod(input.Ctx)).TruncateInt() rewards := input.DistrKeeper.GetValidatorOutstandingRewards(input.Ctx.WithBlockHeight(2), keeper.ValAddrs[0]) require.Equal(t, expectedRewardAmt, rewards.AmountOf(core.MicroSDRDenom).TruncateInt()) rewards = input.DistrKeeper.GetValidatorOutstandingRewards(input.Ctx.WithBlockHeight(2), keeper.ValAddrs[1]) @@ -361,8 +361,10 @@ func TestOracleMultiRewardDistribution(t *testing.T) { EndBlocker(input.Ctx.WithBlockHeight(1), input.OracleKeeper) - expectedRewardAmt := input.OracleKeeper.RewardFraction(input.Ctx).MulInt(stakingAmt.MulRaw(50)).TruncateInt() - expectedRewardAmt2 := input.OracleKeeper.RewardFraction(input.Ctx).MulInt(stakingAmt.MulRaw(25)).TruncateInt() + votePeriod := input.OracleKeeper.VotePeriod(input.Ctx) + rewardDistributedPeriod := input.OracleKeeper.RewardDistributionPeriod(input.Ctx) + expectedRewardAmt := sdk.NewDecFromInt(stakingAmt.MulRaw(50)).MulInt64(votePeriod).QuoInt64(rewardDistributedPeriod).TruncateInt() + expectedRewardAmt2 := sdk.NewDecFromInt(stakingAmt.MulRaw(25)).MulInt64(votePeriod).QuoInt64(rewardDistributedPeriod).TruncateInt() rewards := input.DistrKeeper.GetValidatorOutstandingRewards(input.Ctx.WithBlockHeight(2), keeper.ValAddrs[0]) require.Equal(t, expectedRewardAmt, rewards.AmountOf(core.MicroSDRDenom).TruncateInt()) rewards = input.DistrKeeper.GetValidatorOutstandingRewards(input.Ctx.WithBlockHeight(2), keeper.ValAddrs[1]) diff --git a/x/oracle/alias.go b/x/oracle/alias.go index 019a93d92..4540b2f8b 100644 --- a/x/oracle/alias.go +++ b/x/oracle/alias.go @@ -87,25 +87,27 @@ var ( NewQuerier = keeper.NewQuerier // variable aliases - ModuleCdc = types.ModuleCdc - PrevoteKey = types.PrevoteKey - VoteKey = types.VoteKey - PriceKey = types.PriceKey - FeederDelegationKey = types.FeederDelegationKey - MissedVoteBitArrayKey = types.MissedVoteBitArrayKey - VotingInfoKey = types.VotingInfoKey - ParamStoreKeyVotePeriod = types.ParamStoreKeyVotePeriod - ParamStoreKeyVoteThreshold = types.ParamStoreKeyVoteThreshold - ParamStoreKeyRewardBand = types.ParamStoreKeyRewardBand - ParamStoreKeyRewardFraction = types.ParamStoreKeyRewardFraction - ParamStoreKeyVotesWindow = types.ParamStoreKeyVotesWindow - ParamStoreKeyMinValidVotesPerWindow = types.ParamStoreKeyMinValidVotesPerWindow - ParamStoreKeySlashFraction = types.ParamStoreKeySlashFraction - DefaultVoteThreshold = types.DefaultVoteThreshold - DefaultRewardBand = types.DefaultRewardBand - DefaultRewardFraction = types.DefaultRewardFraction - DefaultMinValidVotesPerWindow = types.DefaultMinValidVotesPerWindow - DefaultSlashFraction = types.DefaultSlashFraction + ModuleCdc = types.ModuleCdc + PrevoteKey = types.PrevoteKey + VoteKey = types.VoteKey + PriceKey = types.PriceKey + FeederDelegationKey = types.FeederDelegationKey + MissedVoteBitArrayKey = types.MissedVoteBitArrayKey + VotingInfoKey = types.VotingInfoKey + ParamStoreKeyVotePeriod = types.ParamStoreKeyVotePeriod + ParamStoreKeyVoteThreshold = types.ParamStoreKeyVoteThreshold + ParamStoreKeyRewardBand = types.ParamStoreKeyRewardBand + ParamStoreKeyRewardDistributionPeriod = types.ParamStoreKeyRewardDistributionPeriod + ParamStoreKeyVotesWindow = types.ParamStoreKeyVotesWindow + ParamStoreKeyMinValidVotesPerWindow = types.ParamStoreKeyMinValidVotesPerWindow + ParamStoreKeySlashFraction = types.ParamStoreKeySlashFraction + ParamStoreKeyWhitelist = types.ParamStoreKeyWhitelist + DefaultVoteThreshold = types.DefaultVoteThreshold + DefaultRewardBand = types.DefaultRewardBand + DefaultRewardDistributionPeriod = types.DefaultRewardDistributionPeriod + DefaultMinValidVotesPerWindow = types.DefaultMinValidVotesPerWindow + DefaultSlashFraction = types.DefaultSlashFraction + DefaultWhitelist = types.DefaultWhitelist ) type ( diff --git a/x/oracle/internal/keeper/keeper_test.go b/x/oracle/internal/keeper/keeper_test.go index 24752e319..a4bdd6fda 100644 --- a/x/oracle/internal/keeper/keeper_test.go +++ b/x/oracle/internal/keeper/keeper_test.go @@ -209,17 +209,17 @@ func TestParams(t *testing.T) { votesWindow := int64(2000) minValidVotesPerWindow := sdk.NewDecWithPrec(1, 2) slashFraction := sdk.NewDecWithPrec(5, 2) - rewardFraction := sdk.NewDecWithPrec(1, 2) + rewardDistributionPeriod := int64(10000000000000) // Should really test validateParams, but skipping because obvious newParams := types.Params{ - VotePeriod: votePeriod, - VoteThreshold: voteThreshold, - RewardBand: oracleRewardBand, - VotesWindow: votesWindow, - MinValidVotesPerWindow: minValidVotesPerWindow, - SlashFraction: slashFraction, - RewardFraction: rewardFraction, + VotePeriod: votePeriod, + VoteThreshold: voteThreshold, + RewardBand: oracleRewardBand, + VotesWindow: votesWindow, + MinValidVotesPerWindow: minValidVotesPerWindow, + SlashFraction: slashFraction, + RewardDistributionPeriod: rewardDistributionPeriod, } input.OracleKeeper.SetParams(input.Ctx, newParams) diff --git a/x/oracle/internal/keeper/params.go b/x/oracle/internal/keeper/params.go index 19dc24839..791877358 100644 --- a/x/oracle/internal/keeper/params.go +++ b/x/oracle/internal/keeper/params.go @@ -6,42 +6,42 @@ import ( "github.com/terra-project/core/x/oracle/internal/types" ) -// ParamTable for staking module +// ParamKeyTable for staking module func ParamKeyTable() params.KeyTable { return params.NewKeyTable().RegisterParamSet(&types.Params{}) } -// VotePeriod +// VotePeriod returns the number of blocks during which voting takes place. func (k Keeper) VotePeriod(ctx sdk.Context) (res int64) { k.paramSpace.Get(ctx, types.ParamStoreKeyVotePeriod, &res) return } -// VoteThreshold +// VoteThreshold returns the minimum percentage of votes that must be received for a ballot to pass. func (k Keeper) VoteThreshold(ctx sdk.Context) (res sdk.Dec) { k.paramSpace.Get(ctx, types.ParamStoreKeyVoteThreshold, &res) return } -// RewardBand +// RewardBand returns the ratio of allowable price error that can be rewared func (k Keeper) RewardBand(ctx sdk.Context) (res sdk.Dec) { k.paramSpace.Get(ctx, types.ParamStoreKeyRewardBand, &res) return } -// RewardFraction -func (k Keeper) RewardFraction(ctx sdk.Context) (res sdk.Dec) { - k.paramSpace.Get(ctx, types.ParamStoreKeyRewardFraction, &res) +// RewardDistributionPeriod returns the number of blocks of the the period during which seigiornage reward comes in and then is distributed. +func (k Keeper) RewardDistributionPeriod(ctx sdk.Context) (res int64) { + k.paramSpace.Get(ctx, types.ParamStoreKeyRewardDistributionPeriod, &res) return } -// VotesWindow +// VotesWindow returns the number of block units on which the penalty is based func (k Keeper) VotesWindow(ctx sdk.Context) (res int64) { k.paramSpace.Get(ctx, types.ParamStoreKeyVotesWindow, &res) return } -// MinValidVotesPerWindow +// MinValidVotesPerWindow returns the minimum number of blocks to avoid slashing in a window func (k Keeper) MinValidVotesPerWindow(ctx sdk.Context) (res int64) { var minValidVotesPerWindow sdk.Dec k.paramSpace.Get(ctx, types.ParamStoreKeyMinValidVotesPerWindow, &minValidVotesPerWindow) @@ -51,12 +51,18 @@ func (k Keeper) MinValidVotesPerWindow(ctx sdk.Context) (res int64) { return minValidVotesPerWindow.MulInt64(signedBlocksWindow).RoundInt64() } -// SlashFraction +// SlashFraction returns the slashing ratio on the delegated token func (k Keeper) SlashFraction(ctx sdk.Context) (res sdk.Dec) { k.paramSpace.Get(ctx, types.ParamStoreKeySlashFraction, &res) return } +// Whitelist returns the denom list that can be acitivated +func (k Keeper) Whitelist(ctx sdk.Context) (res types.DenomList) { + k.paramSpace.Get(ctx, types.ParamStoreKeyWhitelist, &res) + return +} + // GetParams returns the total set of oracle parameters. func (k Keeper) GetParams(ctx sdk.Context) (params types.Params) { k.paramSpace.GetParamSet(ctx, ¶ms) diff --git a/x/oracle/internal/keeper/reward.go b/x/oracle/internal/keeper/reward.go index b8e363495..8588d3e24 100644 --- a/x/oracle/internal/keeper/reward.go +++ b/x/oracle/internal/keeper/reward.go @@ -20,17 +20,22 @@ func (k Keeper) RewardBallotWinners(ctx sdk.Context, ballotWinners types.ClaimPo if prevBallotWeightSum != 0 { rewardPool := k.getRewardPool(ctx) if !rewardPool.Empty() { - // In case rewardFraction = 1%; 1/100 module balance will be distributed - rewardFraction := k.RewardFraction(ctx) + // rewardCoin = (oraclePool / rewardDistributionPeriod) * votePeriod + rewardDistributionPeriod := k.RewardDistributionPeriod(ctx) + votePeriod := k.VotePeriod(ctx) // Dole out rewards var distributedReward sdk.Coins for _, winner := range ballotWinners { rewardCoins := sdk.NewCoins() rewardeeVal := k.StakingKeeper.Validator(ctx, winner.Recipient) - for _, feeCoin := range rewardPool { - rewardAmt := sdk.NewDecFromInt(feeCoin.Amount).Mul(rewardFraction).QuoInt64(prevBallotWeightSum).MulInt64(winner.Weight).TruncateInt() - rewardCoins = append(rewardCoins, sdk.NewCoin(feeCoin.Denom, rewardAmt)) + + for _, poolCoin := range rewardPool { + // The amount of the coin will be distributed in this vote period + totalRewardAmt := sdk.NewDecFromInt(poolCoin.Amount).MulInt64(votePeriod).QuoInt64(rewardDistributionPeriod) + // Reflects contribution + rewardAmt := totalRewardAmt.QuoInt64(prevBallotWeightSum).MulInt64(winner.Weight).TruncateInt() + rewardCoins = append(rewardCoins, sdk.NewCoin(poolCoin.Denom, rewardAmt)) } // In case absence of the validator, we just skip distribution diff --git a/x/oracle/internal/keeper/reward_test.go b/x/oracle/internal/keeper/reward_test.go index 2658312bd..633513c63 100644 --- a/x/oracle/internal/keeper/reward_test.go +++ b/x/oracle/internal/keeper/reward_test.go @@ -46,18 +46,22 @@ func TestRewardBallotWinners(t *testing.T) { claimPool := types.ClaimPool{claim, claim2} // Prepare reward pool - givingAmt := sdk.NewCoins(sdk.NewInt64Coin(core.MicroLunaDenom, 3000)) + givingAmt := sdk.NewCoins(sdk.NewInt64Coin(core.MicroLunaDenom, 3000000)) acc := input.SupplyKeeper.GetModuleAccount(ctx, types.ModuleName) err := acc.SetCoins(givingAmt) require.NoError(t, err) input.SupplyKeeper.SetModuleAccount(ctx, acc) + votePeriod := input.OracleKeeper.VotePeriod(input.Ctx) + rewardDistributionPeriod := input.OracleKeeper.RewardDistributionPeriod(input.Ctx) input.OracleKeeper.RewardBallotWinners(ctx, claimPool) - outstandingRewards := input.DistrKeeper.GetValidatorOutstandingRewards(ctx, addr) - require.Equal(t, sdk.NewDecFromInt(givingAmt.AmountOf(core.MicroLunaDenom)).Mul(input.OracleKeeper.RewardFraction(ctx)).QuoInt64(3), + outstandingRewardsDec := input.DistrKeeper.GetValidatorOutstandingRewards(ctx, addr) + outstandingRewards, _ := outstandingRewardsDec.TruncateDecimal() + require.Equal(t, sdk.NewDecFromInt(givingAmt.AmountOf(core.MicroLunaDenom)).QuoInt64(rewardDistributionPeriod).MulInt64(votePeriod).QuoInt64(3).TruncateInt(), outstandingRewards.AmountOf(core.MicroLunaDenom)) - outstandingRewards1 := input.DistrKeeper.GetValidatorOutstandingRewards(ctx, addr1) - require.Equal(t, sdk.NewDecFromInt(givingAmt.AmountOf(core.MicroLunaDenom)).Mul(input.OracleKeeper.RewardFraction(ctx)).QuoInt64(3).MulInt64(2), + outstandingRewardsDec1 := input.DistrKeeper.GetValidatorOutstandingRewards(ctx, addr1) + outstandingRewards1, _ := outstandingRewardsDec1.TruncateDecimal() + require.Equal(t, sdk.NewDecFromInt(givingAmt.AmountOf(core.MicroLunaDenom)).QuoInt64(rewardDistributionPeriod).MulInt64(votePeriod).QuoInt64(3).MulInt64(2).TruncateInt(), outstandingRewards1.AmountOf(core.MicroLunaDenom)) } diff --git a/x/oracle/internal/types/params.go b/x/oracle/internal/types/params.go index 7b9530065..659959c2d 100644 --- a/x/oracle/internal/types/params.go +++ b/x/oracle/internal/types/params.go @@ -14,13 +14,14 @@ const DefaultParamspace = ModuleName // Parameter keys var ( - ParamStoreKeyVotePeriod = []byte("voteperiod") - ParamStoreKeyVoteThreshold = []byte("votethreshold") - ParamStoreKeyRewardBand = []byte("rewardband") - ParamStoreKeyRewardFraction = []byte("rewardfraction") - ParamStoreKeyVotesWindow = []byte("voteswindow") - ParamStoreKeyMinValidVotesPerWindow = []byte("minvalidvotesperwindow") - ParamStoreKeySlashFraction = []byte("slashfraction") + ParamStoreKeyVotePeriod = []byte("voteperiod") + ParamStoreKeyVoteThreshold = []byte("votethreshold") + ParamStoreKeyRewardBand = []byte("rewardband") + ParamStoreKeyRewardDistributionPeriod = []byte("rewarddistributionperiod") + ParamStoreKeyVotesWindow = []byte("voteswindow") + ParamStoreKeyMinValidVotesPerWindow = []byte("minvalidvotesperwindow") + ParamStoreKeySlashFraction = []byte("slashfraction") + ParamStoreKeyWhitelist = []byte("whitelist") ) // Default parameter values @@ -31,40 +32,43 @@ const ( // Default parameter values var ( - DefaultVoteThreshold = sdk.NewDecWithPrec(50, 2) // 50% - DefaultRewardBand = sdk.NewDecWithPrec(1, 2) // 1% - DefaultRewardFraction = sdk.NewDecWithPrec(1, 2) // 1% - DefaultMinValidVotesPerWindow = sdk.NewDecWithPrec(5, 2) // 5% - DefaultSlashFraction = sdk.NewDecWithPrec(1, 4) // 0.01% + DefaultVoteThreshold = sdk.NewDecWithPrec(50, 2) // 50% + DefaultRewardBand = sdk.NewDecWithPrec(1, 2) // 1% + DefaultRewardDistributionPeriod = core.BlocksPerMonth // 432,000 + DefaultMinValidVotesPerWindow = sdk.NewDecWithPrec(5, 2) // 5% + DefaultSlashFraction = sdk.NewDecWithPrec(1, 4) // 0.01% + DefaultWhitelist = DenomList{core.MicroKRWDenom, core.MicroSDRDenom, core.MicroUSDDenom} // ukrw, usdr, uusd ) var _ subspace.ParamSet = &Params{} // Params oracle parameters type Params struct { - VotePeriod int64 `json:"vote_period" yaml:"vote_period"` - VoteThreshold sdk.Dec `json:"vote_threshold" yaml:"vote_threshold"` - RewardBand sdk.Dec `json:"reward_band" yaml:"reward_band"` - VotesWindow int64 `json:"votes_window" yaml:"votes_window"` - MinValidVotesPerWindow sdk.Dec `json:"min_valid_votes_per_window" yaml:"min_valid_votes_per_window"` - SlashFraction sdk.Dec `json:"slash_fraction" yaml:"slash_fraction"` - RewardFraction sdk.Dec `json:"reward_fraction" yaml:"reward_fraction"` + VotePeriod int64 `json:"vote_period" yaml:"vote_period"` // the number of blocks during which voting takes place. + VoteThreshold sdk.Dec `json:"vote_threshold" yaml:"vote_threshold"` // the minimum percentage of votes that must be received for a ballot to pass. + RewardBand sdk.Dec `json:"reward_band" yaml:"reward_band"` // the ratio of allowable price error that can be rewared. + RewardDistributionPeriod int64 `json:"reward_distribution_period" yaml:"reward_distribution_period"` // the number of blocks of the the period during which seigiornage reward comes in and then is distributed. + VotesWindow int64 `json:"votes_window" yaml:"votes_window"` // the number of blocks units on which the penalty is based. + MinValidVotesPerWindow sdk.Dec `json:"min_valid_votes_per_window" yaml:"min_valid_votes_per_window"` // the minimum number of blocks to avoid slashing in a window. + SlashFraction sdk.Dec `json:"slash_fraction" yaml:"slash_fraction"` // the slashing ratio on the delegated token. + Whitelist DenomList `json:"whitelist" yaml:"whitelist"` // the denom list that can be acitivated, } // DefaultParams creates default oracle module parameters func DefaultParams() Params { return Params{ - VotePeriod: DefaultVotePeriod, - VoteThreshold: DefaultVoteThreshold, - RewardBand: DefaultRewardBand, - RewardFraction: DefaultRewardFraction, - VotesWindow: DefaultVotesWindow, - MinValidVotesPerWindow: DefaultMinValidVotesPerWindow, - SlashFraction: DefaultSlashFraction, + VotePeriod: DefaultVotePeriod, + VoteThreshold: DefaultVoteThreshold, + RewardBand: DefaultRewardBand, + RewardDistributionPeriod: DefaultRewardDistributionPeriod, + VotesWindow: DefaultVotesWindow, + MinValidVotesPerWindow: DefaultMinValidVotesPerWindow, + SlashFraction: DefaultSlashFraction, + Whitelist: DefaultWhitelist, } } -// validate a set of params +// Validate validates a set of params func (params Params) Validate() error { if params.VotePeriod <= 0 { return fmt.Errorf("oracle parameter VotePeriod must be > 0, is %d", params.VotePeriod) @@ -75,8 +79,8 @@ func (params Params) Validate() error { if params.RewardBand.IsNegative() { return fmt.Errorf("oracle parameter RewardBand must be positive") } - if params.RewardFraction.IsNegative() { - return fmt.Errorf("oracle parameter RewardBand must be positive") + if params.RewardDistributionPeriod < params.VotePeriod { + return fmt.Errorf("oracle parameter RewardBand must be bigger or equal than Voteperiod") } if params.VotesWindow <= 10 { return fmt.Errorf("oracle parameter VotesWindow must be > 0, is %d", params.VotesWindow) @@ -98,23 +102,25 @@ func (params *Params) ParamSetPairs() subspace.ParamSetPairs { {Key: ParamStoreKeyVotePeriod, Value: ¶ms.VotePeriod}, {Key: ParamStoreKeyVoteThreshold, Value: ¶ms.VoteThreshold}, {Key: ParamStoreKeyRewardBand, Value: ¶ms.RewardBand}, - {Key: ParamStoreKeyRewardFraction, Value: ¶ms.RewardFraction}, + {Key: ParamStoreKeyRewardDistributionPeriod, Value: ¶ms.RewardDistributionPeriod}, {Key: ParamStoreKeyVotesWindow, Value: ¶ms.VotesWindow}, {Key: ParamStoreKeyMinValidVotesPerWindow, Value: ¶ms.MinValidVotesPerWindow}, {Key: ParamStoreKeySlashFraction, Value: ¶ms.SlashFraction}, + {Key: ParamStoreKeyWhitelist, Value: ¶ms.Whitelist}, } } // String implements fmt.Stringer interface func (params Params) String() string { return fmt.Sprintf(`Treasury Params: - VotePeriod: %d - VoteThreshold: %s - RewardBand: %s - RewardFraction: %s - VotesWindow: %d - MinValidVotesPerWindow: %s - SlashFraction: %s - `, params.VotePeriod, params.VoteThreshold, params.RewardBand, params.RewardFraction, - params.VotesWindow, params.MinValidVotesPerWindow, params.SlashFraction) + VotePeriod: %d + VoteThreshold: %s + RewardBand: %s + RewardDistributionPeriod: %d + VotesWindow: %d + MinValidVotesPerWindow: %s + SlashFraction: %s + Whitelist %s + `, params.VotePeriod, params.VoteThreshold, params.RewardBand, params.RewardDistributionPeriod, + params.VotesWindow, params.MinValidVotesPerWindow, params.SlashFraction, params.Whitelist) } diff --git a/x/oracle/internal/types/params_test.go b/x/oracle/internal/types/params_test.go index b9a53c787..36b222c2e 100644 --- a/x/oracle/internal/types/params_test.go +++ b/x/oracle/internal/types/params_test.go @@ -32,7 +32,7 @@ func TestParamsEqual(t *testing.T) { // negative reward fraction p4 := DefaultParams() - p4.RewardFraction = sdk.NewDecWithPrec(-1, 2) + p4.RewardDistributionPeriod = p4.VotePeriod - 1 err = p4.Validate() require.Error(t, err) diff --git a/x/oracle/tally.go b/x/oracle/tally.go index 5bad19bf8..414056625 100644 --- a/x/oracle/tally.go +++ b/x/oracle/tally.go @@ -23,8 +23,9 @@ func tally(ctx sdk.Context, pb types.PriceBallot, k Keeper) (weightedMedian sdk. } for _, vote := range pb { - if vote.Price.GTE(weightedMedian.Sub(rewardSpread)) && vote.Price.LTE(weightedMedian.Add(rewardSpread)) { - if validator := k.StakingKeeper.Validator(ctx, vote.Voter); validator != nil { + // If a validator is not found, then just ignore the vote + if validator := k.StakingKeeper.Validator(ctx, vote.Voter); validator != nil { + if vote.Price.GTE(weightedMedian.Sub(rewardSpread)) && vote.Price.LTE(weightedMedian.Add(rewardSpread)) { power := validator.GetConsensusPower() ballotWinners = append(ballotWinners, types.Claim{