From 094de0cf8601fa2cc2bbf29042bade1e77b6fe06 Mon Sep 17 00:00:00 2001 From: keruch <53012408+keruch@users.noreply.github.com> Date: Thu, 5 Sep 2024 13:33:30 +0200 Subject: [PATCH] feat(sponsorship): updated the scale system for gauge weights (#1190) Co-authored-by: Omri --- .../dymension/sponsorship/sponsorship.proto | 9 ++- x/sponsorship/client/cli/tx.go | 12 ++-- x/sponsorship/client/cli/tx_test.go | 37 +++++++----- x/sponsorship/keeper/genesis_test.go | 4 +- x/sponsorship/keeper/hooks_test.go | 44 +++++++------- x/sponsorship/keeper/keeper_test.go | 15 +++++ x/sponsorship/keeper/msg_server_test.go | 3 +- x/sponsorship/keeper/votes.go | 4 +- x/sponsorship/keeper/votes_test.go | 58 +++++++++---------- x/sponsorship/types/constants.go | 18 +++++- x/sponsorship/types/genesis_test.go | 6 +- x/sponsorship/types/msgs_test.go | 10 ++-- x/sponsorship/types/params.go | 16 ++--- x/sponsorship/types/params_test.go | 6 +- x/sponsorship/types/sponsorship.pb.go | 9 ++- x/sponsorship/types/types.go | 10 ++-- x/sponsorship/types/types_test.go | 52 ++++++++--------- x/streamer/keeper/distribute_test.go | 28 ++++----- 18 files changed, 190 insertions(+), 151 deletions(-) diff --git a/proto/dymensionxyz/dymension/sponsorship/sponsorship.proto b/proto/dymensionxyz/dymension/sponsorship/sponsorship.proto index 1563b256f..715faeddf 100644 --- a/proto/dymensionxyz/dymension/sponsorship/sponsorship.proto +++ b/proto/dymensionxyz/dymension/sponsorship/sponsorship.proto @@ -106,9 +106,12 @@ message Vote { message GaugeWeight { // GaugeID is the ID of the gauge. uint64 gauge_id = 1; - // Weight is a portion of the voting power that is allocated for the given - // gauge. The value must fall between Params.MinAllocationWeight and 100, - // inclusive. + // Weight is a portion of the voting power that is allocated for the given gauge. + // The value is measured in percentages and must fall between 1 and 100 * 10^18, + // inclusive. The base unit is 10^-18%, so + // * 1 --> 10^-18% + // * 10^18 --> 1% + // * 100 * 10^18 --> 100%. string weight = 2 [ (gogoproto.nullable) = false, (gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int" diff --git a/x/sponsorship/client/cli/tx.go b/x/sponsorship/client/cli/tx.go index 567eadb24..29d9a7ec0 100644 --- a/x/sponsorship/client/cli/tx.go +++ b/x/sponsorship/client/cli/tx.go @@ -105,18 +105,18 @@ func ParseGaugeWeights(inputWeights string) ([]types.GaugeWeight, error) { return nil, fmt.Errorf("invalid gauge ID '%s': %w", idValue[0], err) } - weight, err := strconv.Atoi(idValue[1]) - if err != nil { - return nil, fmt.Errorf("invalid gauge weight '%s': %w", idValue[1], err) + weight, ok := math.NewIntFromString(idValue[1]) + if !ok { + return nil, fmt.Errorf("invalid gauge weight '%s'", idValue[1]) } - if weight < 0 || weight > 100 { - return nil, fmt.Errorf("weight must be between 0 and 100, got %d", weight) + if weight.LT(types.MinAllocationWeight) || weight.GT(types.MaxAllocationWeight) { + return nil, fmt.Errorf("weight must be between 1 and 100 * 10^18, got %s", weight) } weights = append(weights, types.GaugeWeight{ GaugeId: gaugeID, - Weight: math.NewInt(int64(weight)), + Weight: weight, }) } diff --git a/x/sponsorship/client/cli/tx_test.go b/x/sponsorship/client/cli/tx_test.go index 599a05849..dc1cb12c6 100644 --- a/x/sponsorship/client/cli/tx_test.go +++ b/x/sponsorship/client/cli/tx_test.go @@ -20,53 +20,60 @@ func TestParseGaugeWeights(t *testing.T) { }{ { name: "Valid input", - input: "15=60,10=30,12=10", + input: "15=60000000000000000000,10=3000,12=10000", expected: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(60)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(10)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(60)}, + {GaugeId: 10, Weight: math.NewInt(3000)}, + {GaugeId: 12, Weight: math.NewInt(10000)}, }, expectError: false, errorContains: "", }, { name: "Valid, sum of weighs < 100", - input: "15=30,10=30,12=39", + input: "15=30000000000000000000,10=30000000000000000000,12=39000000000000000000", expected: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(30)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(39)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(39)}, }, expectError: false, - errorContains: "invalid gauge weights", + errorContains: "", }, { name: "Invalid input format", - input: "15,10=70,12=10", + input: "15,10=70000000000000000000,12=10000000000000000000", expected: nil, expectError: true, errorContains: "invalid gauge weight format", }, { name: "Weight > 100", - input: "15=101,10=70,12=10", + input: "15=101000000000000000000,10=70000000000000000000,12=10000000000000000000", expected: nil, expectError: true, - errorContains: "weight must be between 0 and 100", + errorContains: "weight must be between 1 and 100 * 10^18, got 101000000000000000000", }, { name: "Weight < 0", input: "15=-10,10=70,12=10", expected: nil, expectError: true, - errorContains: "weight must be between 0 and 100", + errorContains: "weight must be between 1 and 100 * 10^18, got -10", }, { name: "Sum of weighs > 100", - input: "15=30,10=30,12=41", + input: "15=30000000000000000000,10=30000000000000000000,12=41000000000000000000", + expected: nil, + expectError: true, + errorContains: "total weight must be less than 100 * 10^18, got 101000000000000000000", + }, + { + name: "Zero weight", + input: "15=0,10=30000000000000000000,12=41000000000000000000", expected: nil, expectError: true, - errorContains: "invalid gauge weights", + errorContains: "weight must be between 1 and 100 * 10^18, got 0", }, { name: "Empty input", diff --git a/x/sponsorship/keeper/genesis_test.go b/x/sponsorship/keeper/genesis_test.go index 1d30aa52a..f57647aee 100644 --- a/x/sponsorship/keeper/genesis_test.go +++ b/x/sponsorship/keeper/genesis_test.go @@ -32,7 +32,7 @@ func (s *KeeperTestSuite) TestGenesis() { Vote: types.Vote{ VotingPower: math.NewInt(600), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(100)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(100)}, }, }, Validators: []types.ValidatorVotingPower{ @@ -45,7 +45,7 @@ func (s *KeeperTestSuite) TestGenesis() { Vote: types.Vote{ VotingPower: math.NewInt(400), Weights: []types.GaugeWeight{ - {GaugeId: 2, Weight: math.NewInt(100)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(100)}, }, }, Validators: []types.ValidatorVotingPower{ diff --git a/x/sponsorship/keeper/hooks_test.go b/x/sponsorship/keeper/hooks_test.go index ca90966c1..adfc64e53 100644 --- a/x/sponsorship/keeper/hooks_test.go +++ b/x/sponsorship/keeper/hooks_test.go @@ -27,8 +27,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -63,8 +63,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -97,8 +97,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -134,8 +134,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -168,8 +168,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -201,8 +201,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -231,8 +231,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -267,8 +267,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -295,8 +295,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -329,8 +329,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) @@ -366,8 +366,8 @@ func (s *KeeperTestSuite) TestHooks() { s.Vote(types.MsgVote{ Voter: del.GetDelegatorAddr().String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(50)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(50)}, }, }) diff --git a/x/sponsorship/keeper/keeper_test.go b/x/sponsorship/keeper/keeper_test.go index b5485691f..439446b5a 100644 --- a/x/sponsorship/keeper/keeper_test.go +++ b/x/sponsorship/keeper/keeper_test.go @@ -48,6 +48,8 @@ func (s *KeeperTestSuite) SetupTest() { s.Ctx = ctx s.queryClient = queryClient s.msgServer = msgServer + + s.SetDefaultTestParams() } func (s *KeeperTestSuite) CreateGauge() uint64 { @@ -288,3 +290,16 @@ func (s *KeeperTestSuite) AssertDelegatorValidator(delAddr sdk.AccAddress, valAd s.Require().NoError(err) s.Require().Equal(expectedPower, vp) } + +// SetDefaultTestParams sets module params with MinVotingPower = 1 for convenience. +func (s *KeeperTestSuite) SetDefaultTestParams() { + err := s.App.SponsorshipKeeper.SetParams(s.Ctx, DefaultTestParams()) + s.Require().NoError(err) +} + +// DefaultTestParams returns module params with MinVotingPower = 1 for convenience. +func DefaultTestParams() types.Params { + params := types.DefaultParams() + params.MinVotingPower = math.NewInt(1) + return params +} diff --git a/x/sponsorship/keeper/msg_server_test.go b/x/sponsorship/keeper/msg_server_test.go index 686927d94..2531c41f3 100644 --- a/x/sponsorship/keeper/msg_server_test.go +++ b/x/sponsorship/keeper/msg_server_test.go @@ -1,7 +1,6 @@ package keeper_test import ( - "cosmossdk.io/math" sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" govtypes "github.com/cosmos/cosmos-sdk/x/gov/types" @@ -46,7 +45,7 @@ func (s *KeeperTestSuite) TestUpdateParams() { msg: types.MsgUpdateParams{ Authority: authority, NewParams: types.Params{ - MinAllocationWeight: math.NewInt(101), // > 100% + MinAllocationWeight: types.DYM.MulRaw(101), // > 100% MinVotingPower: types.DefaultMinVotingPower, }, }, diff --git a/x/sponsorship/keeper/votes.go b/x/sponsorship/keeper/votes.go index 4841efc47..80aa6a009 100644 --- a/x/sponsorship/keeper/votes.go +++ b/x/sponsorship/keeper/votes.go @@ -41,7 +41,7 @@ func (k Keeper) Vote(ctx sdk.Context, voter sdk.AccAddress, weights []types.Gaug // Validate that the user has min voting power if vpBreakdown.TotalPower.LT(params.MinVotingPower) { - return types.Vote{}, types.Distribution{}, fmt.Errorf("voting power '%d' is less than min voting power expected '%d'", vpBreakdown.TotalPower.Int64(), params.MinVotingPower.Int64()) + return types.Vote{}, types.Distribution{}, fmt.Errorf("voting power '%s' is less than min voting power expected '%s'", vpBreakdown.TotalPower, params.MinVotingPower) } // Apply the vote weights to the power -> get a distribution update in absolute values @@ -111,7 +111,7 @@ func (k Keeper) revokeVote(ctx sdk.Context, voter sdk.AccAddress, vote types.Vot func (k Keeper) validateWeights(ctx sdk.Context, weights []types.GaugeWeight, minAllocationWeight math.Int) error { for _, weight := range weights { if weight.Weight.LT(minAllocationWeight) { - return fmt.Errorf("gauge weight '%d' is less than min allocation weight '%d'", weight.Weight.Int64(), minAllocationWeight.Int64()) + return fmt.Errorf("gauge weight '%s' is less than min allocation weight '%s'", weight.Weight, minAllocationWeight) } gauge, err := k.incentivesKeeper.GetGaugeByID(ctx, weight.GaugeId) diff --git a/x/sponsorship/keeper/votes_test.go b/x/sponsorship/keeper/votes_test.go index 929d381f9..91103a358 100644 --- a/x/sponsorship/keeper/votes_test.go +++ b/x/sponsorship/keeper/votes_test.go @@ -30,7 +30,7 @@ func (s *KeeperTestSuite) TestMsgVote() { }{ { name: "Valid, 1 voter, empty initial", - params: types.DefaultParams(), + params: DefaultTestParams(), numGauges: 2, delegations: []delegation{ { @@ -42,8 +42,8 @@ func (s *KeeperTestSuite) TestMsgVote() { { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, }, }, }, @@ -60,7 +60,7 @@ func (s *KeeperTestSuite) TestMsgVote() { }, { name: "Valid, 1 voter, non-empty initial", - params: types.DefaultParams(), + params: DefaultTestParams(), numGauges: 2, delegations: []delegation{ { @@ -72,8 +72,8 @@ func (s *KeeperTestSuite) TestMsgVote() { { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, }, }, }, @@ -96,7 +96,7 @@ func (s *KeeperTestSuite) TestMsgVote() { }, { name: "Valid, 3 voters, non-empty initial", - params: types.DefaultParams(), + params: DefaultTestParams(), numGauges: 3, delegations: []delegation{ { @@ -117,24 +117,24 @@ func (s *KeeperTestSuite) TestMsgVote() { { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 3, Weight: math.NewInt(40)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 3, Weight: types.DYM.MulRaw(40)}, }, }, // [gauge1, 0%] [gauge2, 30%] [gauge3, 20%] power = 1_000_000 { Voter: addr[1].String(), Weights: []types.GaugeWeight{ - {GaugeId: 2, Weight: math.NewInt(30)}, - {GaugeId: 3, Weight: math.NewInt(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 3, Weight: types.DYM.MulRaw(20)}, }, }, // [gauge1, 40%] [gauge2, 20%] [gauge3, 0%] power = 1_000_000 { Voter: addr[2].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(40)}, - {GaugeId: 2, Weight: math.NewInt(20)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(40)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(20)}, }, }, }, @@ -159,7 +159,7 @@ func (s *KeeperTestSuite) TestMsgVote() { }, { name: "Voter re-votes", - params: types.DefaultParams(), + params: DefaultTestParams(), numGauges: 2, delegations: []delegation{ { @@ -171,15 +171,15 @@ func (s *KeeperTestSuite) TestMsgVote() { { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, }, }, { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(50)}, - {GaugeId: 2, Weight: math.NewInt(40)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(50)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(40)}, }, }, }, @@ -202,7 +202,7 @@ func (s *KeeperTestSuite) TestMsgVote() { }, { name: "Unknown gauge", - params: types.DefaultParams(), + params: DefaultTestParams(), numGauges: 1, delegations: []delegation{ { @@ -214,8 +214,8 @@ func (s *KeeperTestSuite) TestMsgVote() { { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, }, }, }, @@ -237,7 +237,7 @@ func (s *KeeperTestSuite) TestMsgVote() { { name: "Weight is less than the min allocation", params: types.Params{ - MinAllocationWeight: math.NewInt(30), + MinAllocationWeight: types.DYM.MulRaw(30), MinVotingPower: types.DefaultMinVotingPower, }, numGauges: 2, @@ -251,8 +251,8 @@ func (s *KeeperTestSuite) TestMsgVote() { { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, }, }, }, @@ -271,7 +271,7 @@ func (s *KeeperTestSuite) TestMsgVote() { }, }, expectErr: true, - errorContains: "gauge weight '20' is less than min allocation weight '30'", + errorContains: "gauge weight '20000000000000000000' is less than min allocation weight '30000000000000000000'", }, { name: "Not enough voting power", @@ -290,8 +290,8 @@ func (s *KeeperTestSuite) TestMsgVote() { { Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, }, }, }, @@ -403,8 +403,8 @@ func (s *KeeperTestSuite) TestMsgRevokeVote() { vote: types.MsgVote{ Voter: addr[0].String(), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(20)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 2, Weight: types.DYM.MulRaw(30)}, }, }, expectErr: false, diff --git a/x/sponsorship/types/constants.go b/x/sponsorship/types/constants.go index 1e432189a..95a86a559 100644 --- a/x/sponsorship/types/constants.go +++ b/x/sponsorship/types/constants.go @@ -5,8 +5,20 @@ import ( ) var ( - hundred = math.NewInt(100) + // ADYM represents 1 ADYM. + ADYM = math.NewInt(1) + // DYM represents 1 DYM. Equals to 10^18 ADYM. + DYM = math.NewIntWithDecimal(1, 18) - DefaultMinAllocationWeight = math.NewInt(1) // 1% - DefaultMinVotingPower = math.NewInt(1) // 1 DYM + // MinAllocationWeight is a min weight one can allocate for the gauge. + // Equals 1 and is measured in percentages. + // 1 unit is 10^-18%. + MinAllocationWeight = ADYM + // MaxAllocationWeight is a max weight one can allocate for the gauge. + // Equals 100 * 10^18 and is measured in percentages. + // 1 unit is 10^-18%. 100 * 10^18 is 100%. + MaxAllocationWeight = DYM.MulRaw(100) + + DefaultMinAllocationWeight = DYM // 1% + DefaultMinVotingPower = DYM // 1 DYM ) diff --git a/x/sponsorship/types/genesis_test.go b/x/sponsorship/types/genesis_test.go index 555d08ab1..1cbbf6729 100644 --- a/x/sponsorship/types/genesis_test.go +++ b/x/sponsorship/types/genesis_test.go @@ -203,13 +203,13 @@ func TestValidateVoterInfo(t *testing.T) { errorContains: "voter 'asdasd' must be a valid bech32 address", }, { - name: "Invalid vote: weight > 100", + name: "Invalid vote: weight > 100 * 10^18", input: types.VoterInfo{ Voter: addrs[0], Vote: types.Vote{ VotingPower: math.NewInt(600), Weights: []types.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(101)}, // <-- 101% + {GaugeId: 1, Weight: types.DYM.MulRaw(101)}, // <-- 101% }, }, Validators: []types.ValidatorVotingPower{ @@ -218,7 +218,7 @@ func TestValidateVoterInfo(t *testing.T) { }, }, errorIs: types.ErrInvalidVoterInfo, - errorContains: "weight must be <= 100, got 101", + errorContains: "weight must be <= 100 * 10^18, got 101000000000000000000", }, { name: "Invalid validators: duplicated addresses", diff --git a/x/sponsorship/types/msgs_test.go b/x/sponsorship/types/msgs_test.go index 7b236cec0..559f56a00 100644 --- a/x/sponsorship/types/msgs_test.go +++ b/x/sponsorship/types/msgs_test.go @@ -47,17 +47,17 @@ func TestMsgVote(t *testing.T) { errorContains: "voter '123123' must be a valid bech32 address", }, { - name: "Invalid distribution, Weight > 100", + name: "Invalid distribution, Weight > 100 * 10^18", input: types.MsgVote{ Voter: addrs[0], Weights: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(101)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(10)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(101)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(10)}, }, }, errorIs: types.ErrInvalidDistribution, - errorContains: "weight must be <= 100", + errorContains: "weight must be <= 100 * 10^18", }, } diff --git a/x/sponsorship/types/params.go b/x/sponsorship/types/params.go index a634cbefe..27099b04f 100644 --- a/x/sponsorship/types/params.go +++ b/x/sponsorship/types/params.go @@ -21,13 +21,13 @@ func DefaultParams() Params { func (p Params) Validate() error { if p.MinAllocationWeight.IsNegative() { - return ErrInvalidParams.Wrapf("MinAllocationWeight must be >= 0, got %d", p.MinAllocationWeight.Int64()) + return ErrInvalidParams.Wrapf("MinAllocationWeight must be >= 0, got %s", p.MinAllocationWeight) } - if p.MinAllocationWeight.GT(hundred) { - return ErrInvalidParams.Wrapf("MinAllocationWeight must be <= 100, got %d", p.MinAllocationWeight.Int64()) + if p.MinAllocationWeight.GT(MaxAllocationWeight) { + return ErrInvalidParams.Wrapf("MinAllocationWeight must be <= 100 * 10^18, got %s", p.MinAllocationWeight) } if p.MinVotingPower.IsNegative() { - return ErrInvalidParams.Wrapf("MinVotingPower must be >= 0, got %d", p.MinVotingPower.Int64()) + return ErrInvalidParams.Wrapf("MinVotingPower must be >= 0, got %s", p.MinVotingPower) } return nil } @@ -53,10 +53,10 @@ func validateMinAllocationWeight(i interface{}) error { } if value.IsNegative() { - return ErrInvalidParams.Wrapf("MinAllocationWeight must be >= 0, got %d", value.Int64()) + return ErrInvalidParams.Wrapf("MinAllocationWeight must be >= 0, got %s", value) } - if value.GT(hundred) { - return ErrInvalidParams.Wrapf("MinAllocationWeight must be <= 100, got %d", value.Int64()) + if value.GT(MaxAllocationWeight) { + return ErrInvalidParams.Wrapf("MinAllocationWeight must be <= 100 * 10^18, got %s", value) } return nil @@ -69,7 +69,7 @@ func validateMinVotingPower(i interface{}) error { } if value.IsNegative() { - return ErrInvalidParams.Wrapf("MinVotingPower must be >= 0, got %d", value.Int64()) + return ErrInvalidParams.Wrapf("MinVotingPower must be >= 0, got %s", value) } return nil diff --git a/x/sponsorship/types/params_test.go b/x/sponsorship/types/params_test.go index f5c29e4ac..0359b6dc4 100644 --- a/x/sponsorship/types/params_test.go +++ b/x/sponsorship/types/params_test.go @@ -41,13 +41,13 @@ func TestParams(t *testing.T) { errorContains: "MinAllocationWeight must be >= 0", }, { - name: "MinAllocationWeight > 100", + name: "MinAllocationWeight > 100 * 10^18", input: types.Params{ - MinAllocationWeight: math.NewInt(110), + MinAllocationWeight: types.DYM.MulRaw(110), MinVotingPower: math.NewInt(20), }, errorIs: types.ErrInvalidParams, - errorContains: "MinAllocationWeight must be <= 100", + errorContains: "MinAllocationWeight must be <= 100 * 10^18, got 110000000000000000000", }, { name: "MinVotingPower < 0", diff --git a/x/sponsorship/types/sponsorship.pb.go b/x/sponsorship/types/sponsorship.pb.go index be24d9f3e..a7a61a581 100644 --- a/x/sponsorship/types/sponsorship.pb.go +++ b/x/sponsorship/types/sponsorship.pb.go @@ -270,9 +270,12 @@ func (m *Vote) GetWeights() []GaugeWeight { type GaugeWeight struct { // GaugeID is the ID of the gauge. GaugeId uint64 `protobuf:"varint,1,opt,name=gauge_id,json=gaugeId,proto3" json:"gauge_id,omitempty"` - // Weight is a portion of the voting power that is allocated for the given - // gauge. The value must fall between Params.MinAllocationWeight and 100, - // inclusive. + // Weight is a portion of the voting power that is allocated for the given gauge. + // The value is measured in percentages and must fall between 1 and 100 * 10^18, + // inclusive. The base unit is 10^-18%, so + // - 1 --> 10^-18% + // - 10^18 --> 1% + // - 100 * 10^18 --> 100%. Weight github_com_cosmos_cosmos_sdk_types.Int `protobuf:"bytes,2,opt,name=weight,proto3,customtype=github.com/cosmos/cosmos-sdk/types.Int" json:"weight"` } diff --git a/x/sponsorship/types/types.go b/x/sponsorship/types/types.go index faf57c068..9056a0bb8 100644 --- a/x/sponsorship/types/types.go +++ b/x/sponsorship/types/types.go @@ -45,8 +45,8 @@ func ValidateGaugeWeights(w []GaugeWeight) error { gaugeIDs[g.GaugeId] = struct{}{} total = total.Add(g.Weight) } - if total.GT(hundred) { - return ErrInvalidGaugeWeight.Wrapf("total weight must be less than 100, got %s", total) + if total.GT(MaxAllocationWeight) { + return ErrInvalidGaugeWeight.Wrapf("total weight must be less than 100 * 10^18, got %s", total) } return nil } @@ -55,8 +55,8 @@ func (g GaugeWeight) Validate() error { if !g.Weight.IsPositive() { return ErrInvalidGaugeWeight.Wrapf("weight must be > 0, got %s", g.Weight) } - if g.Weight.GT(hundred) { - return ErrInvalidGaugeWeight.Wrapf("weight must be <= 100, got %s", g.Weight) + if g.Weight.GT(MaxAllocationWeight) { + return ErrInvalidGaugeWeight.Wrapf("weight must be <= 100 * 10^18, got %s", g.Weight) } return nil } @@ -71,7 +71,7 @@ func ApplyWeights(votingPower math.Int, weights []GaugeWeight) Distribution { for _, weight := range weights { gauges = append(gauges, Gauge{ GaugeId: weight.GetGaugeId(), - Power: votingPower.Mul(weight.Weight).Quo(hundred), + Power: votingPower.Mul(weight.Weight).Quo(MaxAllocationWeight), }) } diff --git a/x/sponsorship/types/types_test.go b/x/sponsorship/types/types_test.go index 9d3a50a6a..b328d21c5 100644 --- a/x/sponsorship/types/types_test.go +++ b/x/sponsorship/types/types_test.go @@ -31,12 +31,12 @@ func TestValidateGaugeWeights(t *testing.T) { { name: "Weight > 100", input: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(101)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(10)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(101)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(10)}, }, errorIs: types.ErrInvalidGaugeWeight, - errorContains: "weight must be <= 100", + errorContains: "weight must be <= 100 * 10^18, got 101000000000000000000", }, { name: "Weight < 0", @@ -59,14 +59,14 @@ func TestValidateGaugeWeights(t *testing.T) { errorContains: "weight must be > 0", }, { - name: "Sum of weighs > 100", + name: "Sum of weighs > 100 * 10^18", input: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(60)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(20)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(60)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(20)}, }, errorIs: types.ErrInvalidGaugeWeight, - errorContains: "total weight must be less than 100, got 110", + errorContains: "total weight must be less than 100 * 10^18, got 110000000000000000000", }, { name: "Valid, sum of weighs < 100", @@ -212,17 +212,17 @@ func TestValidateVote(t *testing.T) { errorContains: "", }, { - name: "Invalid weights: weight > 100", + name: "Invalid weights: weight > 100 * 10^18", input: types.Vote{ VotingPower: math.NewInt(1000), Weights: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(101)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(10)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(101)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(10)}, }, }, errorIs: types.ErrInvalidVote, - errorContains: "weight must be <= 100", + errorContains: "weight must be <= 100 * 10^18", }, } @@ -251,12 +251,12 @@ func TestApplyWeights(t *testing.T) { expected types.Distribution }{ { - name: "Positive power, sum weights == 1", + name: "Positive power, sum weights == 100%", power: math.NewInt(1000), weights: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(60)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(10)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(60)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(10)}, }, expected: types.Distribution{ VotingPower: math.NewInt(1000), @@ -268,12 +268,12 @@ func TestApplyWeights(t *testing.T) { }, }, { - name: "Positive power, sum weights < 1", + name: "Positive power, sum weights < 100%", power: math.NewInt(1000), weights: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(30)}, - {GaugeId: 10, Weight: math.NewInt(20)}, - {GaugeId: 12, Weight: math.NewInt(10)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(20)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(10)}, }, expected: types.Distribution{ VotingPower: math.NewInt(1000), @@ -285,12 +285,12 @@ func TestApplyWeights(t *testing.T) { }, }, { - name: "Negative power, sum weights == 1", + name: "Negative power, sum weights == 100%", power: math.NewInt(-1000), weights: []types.GaugeWeight{ - {GaugeId: 15, Weight: math.NewInt(60)}, - {GaugeId: 10, Weight: math.NewInt(30)}, - {GaugeId: 12, Weight: math.NewInt(10)}, + {GaugeId: 15, Weight: types.DYM.MulRaw(60)}, + {GaugeId: 10, Weight: types.DYM.MulRaw(30)}, + {GaugeId: 12, Weight: types.DYM.MulRaw(10)}, }, expected: types.Distribution{ VotingPower: math.NewInt(-1000), diff --git a/x/streamer/keeper/distribute_test.go b/x/streamer/keeper/distribute_test.go index ced632650..2ff0f70b1 100644 --- a/x/streamer/keeper/distribute_test.go +++ b/x/streamer/keeper/distribute_test.go @@ -137,8 +137,8 @@ func (suite *KeeperTestSuite) TestSponsoredDistribute() { initialVote: sponsorshiptypes.MsgVote{ Voter: addrs[0].String(), Weights: []sponsorshiptypes.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(50)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: sponsorshiptypes.DYM.MulRaw(50)}, + {GaugeId: 2, Weight: sponsorshiptypes.DYM.MulRaw(30)}, }, }, hasIntermediateDistr: false, @@ -158,8 +158,8 @@ func (suite *KeeperTestSuite) TestSponsoredDistribute() { intermediateVote: sponsorshiptypes.MsgVote{ Voter: addrs[1].String(), Weights: []sponsorshiptypes.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(10)}, - {GaugeId: 2, Weight: math.NewInt(90)}, + {GaugeId: 1, Weight: sponsorshiptypes.DYM.MulRaw(10)}, + {GaugeId: 2, Weight: sponsorshiptypes.DYM.MulRaw(90)}, }, }, filledEpochs: 1, @@ -175,16 +175,16 @@ func (suite *KeeperTestSuite) TestSponsoredDistribute() { initialVote: sponsorshiptypes.MsgVote{ Voter: addrs[0].String(), Weights: []sponsorshiptypes.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(70)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: sponsorshiptypes.DYM.MulRaw(70)}, + {GaugeId: 2, Weight: sponsorshiptypes.DYM.MulRaw(30)}, }, }, hasIntermediateDistr: true, intermediateVote: sponsorshiptypes.MsgVote{ Voter: addrs[1].String(), Weights: []sponsorshiptypes.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(10)}, - {GaugeId: 2, Weight: math.NewInt(90)}, + {GaugeId: 1, Weight: sponsorshiptypes.DYM.MulRaw(10)}, + {GaugeId: 2, Weight: sponsorshiptypes.DYM.MulRaw(90)}, }, }, filledEpochs: 1, @@ -210,16 +210,16 @@ func (suite *KeeperTestSuite) TestSponsoredDistribute() { initialVote: sponsorshiptypes.MsgVote{ Voter: addrs[0].String(), Weights: []sponsorshiptypes.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(70)}, - {GaugeId: 2, Weight: math.NewInt(30)}, + {GaugeId: 1, Weight: sponsorshiptypes.DYM.MulRaw(70)}, + {GaugeId: 2, Weight: sponsorshiptypes.DYM.MulRaw(30)}, }, }, hasIntermediateDistr: true, intermediateVote: sponsorshiptypes.MsgVote{ Voter: addrs[1].String(), Weights: []sponsorshiptypes.GaugeWeight{ - {GaugeId: 1, Weight: math.NewInt(10)}, - {GaugeId: 2, Weight: math.NewInt(90)}, + {GaugeId: 1, Weight: sponsorshiptypes.DYM.MulRaw(10)}, + {GaugeId: 2, Weight: sponsorshiptypes.DYM.MulRaw(90)}, }, }, filledEpochs: 1, @@ -231,7 +231,7 @@ func (suite *KeeperTestSuite) TestSponsoredDistribute() { // Cast an initial vote if tc.hasInitialDistr { - suite.Vote(tc.initialVote, math.NewInt(1_000_000)) + suite.Vote(tc.initialVote, sponsorshiptypes.DYM) } // Create a stream @@ -248,7 +248,7 @@ func (suite *KeeperTestSuite) TestSponsoredDistribute() { // Cast an intermediate vote if tc.hasIntermediateDistr { - suite.Vote(tc.intermediateVote, math.NewInt(1_000_000)) + suite.Vote(tc.intermediateVote, sponsorshiptypes.DYM) } // Distribute