Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(incentives): added fees for adding to gauge and gauge creation #1188

Merged
merged 9 commits into from
Sep 16, 2024
Merged
13 changes: 7 additions & 6 deletions app/upgrades/v3/upgrade_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
cometbftproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
upgradetypes "github.com/cosmos/cosmos-sdk/x/upgrade/types"
incentivestypes "github.com/dymensionxyz/dymension/v3/x/incentives/types"
"github.com/stretchr/testify/suite"

"github.com/dymensionxyz/dymension/v3/app"
Expand Down Expand Up @@ -39,9 +38,9 @@ var (
DYM = sdk.NewIntFromBigInt(new(big.Int).Exp(big.NewInt(10), big.NewInt(18), nil))

// CreateGaugeFee is the fee required to create a new gauge.
expectCreateGaugeFee = DYM.Mul(sdk.NewInt(10))
// expectCreateGaugeFee = DYM.Mul(sdk.NewInt(10))
// AddToGaugeFee is the fee required to add to gauge.
expectAddToGaugeFee = sdk.ZeroInt()
// expectAddToGaugeFee = sdk.ZeroInt()

expectDelayedackEpochIdentifier = "hour"
expectDelayedackBridgingFee = sdk.NewDecWithPrec(1, 3)
Expand Down Expand Up @@ -102,10 +101,12 @@ func (s *UpgradeTestSuite) TestUpgrade() {
return fmt.Errorf("sequencer parameters not set correctly")
}

// These fields are deleted in the v4 update. Intentionally leave the commented code
// here for historical reference.
// Check Incentives parameters
if !incentivestypes.CreateGaugeFee.Equal(expectCreateGaugeFee) || !incentivestypes.AddToGaugeFee.Equal(expectAddToGaugeFee) {
return fmt.Errorf("incentives parameters not set correctly")
}
//if !incentivestypes.CreateGaugeFee.Equal(expectCreateGaugeFee) || !incentivestypes.AddToGaugeFee.Equal(expectAddToGaugeFee) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not a fan of commented code! :D

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's an old state migration (v3 while current is v4), and i didn't want to modify old migration scripts, so i intentionally left this code commented here to have a historical reference. added an explanation comment for that.

// return fmt.Errorf("incentives parameters not set correctly")
//}

return nil
},
Expand Down
12 changes: 12 additions & 0 deletions app/upgrades/v4/upgrade.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import (
"github.com/dymensionxyz/dymension/v3/app/upgrades"
delayedackkeeper "github.com/dymensionxyz/dymension/v3/x/delayedack/keeper"
delayedacktypes "github.com/dymensionxyz/dymension/v3/x/delayedack/types"
incentiveskeeper "github.com/dymensionxyz/dymension/v3/x/incentives/keeper"
incentivestypes "github.com/dymensionxyz/dymension/v3/x/incentives/types"
lightclientkeeper "github.com/dymensionxyz/dymension/v3/x/lightclient/keeper"
rollappkeeper "github.com/dymensionxyz/dymension/v3/x/rollapp/keeper"
rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types"
Expand Down Expand Up @@ -62,6 +64,7 @@ func CreateUpgradeHandler(
if err := migrateStreamer(ctx, keepers.StreamerKeeper, keepers.EpochsKeeper); err != nil {
return nil, err
}
migrateIncentivesParams(ctx, keepers.IncentivesKeeper)

// TODO: create rollapp gauges for each existing rollapp (https://github.com/dymensionxyz/dymension/issues/1005)

Expand Down Expand Up @@ -190,6 +193,15 @@ func migrateStreamer(ctx sdk.Context, sk streamerkeeper.Keeper, ek *epochskeeper
return nil
}

func migrateIncentivesParams(ctx sdk.Context, ik *incentiveskeeper.Keeper) {
params := ik.GetParams(ctx)
defaultParams := incentivestypes.DefaultParams()
params.CreateGaugeBaseFee = defaultParams.CreateGaugeBaseFee
params.AddToGaugeBaseFee = defaultParams.AddToGaugeBaseFee
params.AddDenomFee = defaultParams.AddDenomFee
ik.SetParams(ctx, params)
}

func ConvertOldRollappToNew(oldRollapp rollapptypes.Rollapp) rollapptypes.Rollapp {
return rollapptypes.Rollapp{
RollappId: oldRollapp.RollappId,
Expand Down
19 changes: 19 additions & 0 deletions proto/dymensionxyz/dymension/incentives/params.proto
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,23 @@ message Params {
// (day, week, etc.)
string distr_epoch_identifier = 1
[ (gogoproto.moretags) = "yaml:\"distr_epoch_identifier\"" ];
// CreateGaugeBaseFee is a base fee required to create a new gauge. The final
// fee is calculated as
// Fee = CreateGaugeBaseFee + AddDenomFee * (len(Denoms) + len(GaugeDenoms)).
string create_gauge_base_fee = 2 [
(gogoproto.nullable) = false,
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int"
];
// AddToGaugeBaseFee is a base fee required to add to gauge. The final
// fee is calculated as
// Fee = AddToGaugeBaseFee + AddDenomFee * len(Denoms).
string add_to_gauge_base_fee = 3 [
(gogoproto.nullable) = false,
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int"
];
// AddDenomFee is a fee charged for adding every new denom to the gauge.
string add_denom_fee = 4 [
(gogoproto.nullable) = false,
(gogoproto.customtype) = "github.com/cosmos/cosmos-sdk/types.Int"
];
}
21 changes: 14 additions & 7 deletions x/incentives/keeper/gauge.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,27 +141,34 @@ func (k Keeper) CreateGauge(ctx sdk.Context, isPerpetual bool, owner sdk.AccAddr
}

// AddToGaugeRewards adds coins to gauge.
func (k Keeper) AddToGaugeRewards(ctx sdk.Context, owner sdk.AccAddress, coins sdk.Coins, gaugeID uint64) error {
gauge, err := k.GetGaugeByID(ctx, gaugeID)
if err != nil {
return err
}
func (k Keeper) AddToGaugeRewards(ctx sdk.Context, owner sdk.AccAddress, coins sdk.Coins, gauge *types.Gauge) error {
if gauge.IsFinishedGauge(ctx.BlockTime()) {
return types.UnexpectedFinishedGaugeError{GaugeId: gaugeID}
return types.UnexpectedFinishedGaugeError{GaugeId: gauge.Id}
}

if err := k.bk.SendCoinsFromAccountToModule(ctx, owner, types.ModuleName, coins); err != nil {
return err
}

gauge.Coins = gauge.Coins.Add(coins...)
err = k.setGauge(ctx, gauge)
err := k.setGauge(ctx, gauge)
if err != nil {
return err
}
k.hooks.AfterAddToGauge(ctx, gauge.Id)
return nil
}

// AddToGaugeRewardsByID adds coins to gauge.
// TODO: Used only in x/streamer. Delete after https://github.com/dymensionxyz/dymension/pull/1173 is merged!
func (k Keeper) AddToGaugeRewardsByID(ctx sdk.Context, owner sdk.AccAddress, coins sdk.Coins, gaugeID uint64) error {
gauge, err := k.GetGaugeByID(ctx, gaugeID)
if err != nil {
return err
}
return k.AddToGaugeRewards(ctx, owner, coins, gauge)
}

// GetGaugeByID returns gauge from gauge ID.
func (k Keeper) GetGaugeByID(ctx sdk.Context, gaugeID uint64) (*types.Gauge, error) {
gauge := types.Gauge{}
Expand Down
4 changes: 4 additions & 0 deletions x/incentives/keeper/genesis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"
"time"

"cosmossdk.io/math"
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
sdk "github.com/cosmos/cosmos-sdk/types"
bankutil "github.com/cosmos/cosmos-sdk/x/bank/testutil"
Expand Down Expand Up @@ -97,6 +98,9 @@ func TestIncentivesInitGenesis(t *testing.T) {
app.IncentivesKeeper.InitGenesis(ctx, types.GenesisState{
Params: types.Params{
DistrEpochIdentifier: "week",
CreateGaugeBaseFee: math.ZeroInt(),
AddToGaugeBaseFee: math.ZeroInt(),
AddDenomFee: math.ZeroInt(),
},
Gauges: []types.Gauge{gauge},
LockableDurations: []time.Duration{
Expand Down
27 changes: 20 additions & 7 deletions x/incentives/keeper/msg_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,12 @@ package keeper
import (
"context"

"github.com/dymensionxyz/dymension/v3/x/incentives/types"
"github.com/osmosis-labs/osmosis/v15/osmoutils"

errorsmod "cosmossdk.io/errors"

sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
"github.com/osmosis-labs/osmosis/v15/osmoutils"

"github.com/dymensionxyz/dymension/v3/x/incentives/types"
)

// msgServer provides a way to reference keeper pointer in the message server interface.
Expand All @@ -35,7 +34,11 @@ func (server msgServer) CreateGauge(goCtx context.Context, msg *types.MsgCreateG
return nil, err
}

if err := server.keeper.chargeFeeIfSufficientFeeDenomBalance(ctx, owner, types.CreateGaugeFee, msg.Coins); err != nil {
// Charge fess based on the number of coins to add
// Fee = CreateGaugeBaseFee + AddDenomFee * NumDenoms
params := server.keeper.GetParams(ctx)
fee := params.CreateGaugeBaseFee.Add(params.AddDenomFee.MulRaw(int64(len(msg.Coins))))
if err = server.keeper.chargeFeeIfSufficientFeeDenomBalance(ctx, owner, fee, msg.Coins); err != nil {
return nil, err
}

Expand Down Expand Up @@ -63,10 +66,20 @@ func (server msgServer) AddToGauge(goCtx context.Context, msg *types.MsgAddToGau
return nil, err
}

if err := server.keeper.chargeFeeIfSufficientFeeDenomBalance(ctx, owner, types.AddToGaugeFee, msg.Rewards); err != nil {
gauge, err := server.keeper.GetGaugeByID(ctx, msg.GaugeId)
if err != nil {
return nil, err
}

// Charge fess based on the number of coins to add
// Fee = AddToGaugeBaseFee + AddDenomFee * (NumAddedDenoms + NumGaugeDenoms)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do we need to pay for existing denoms as well? Isn't it already paid for when added initially?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to prevent spam where somebody keeps excessively adding funds to some already overloaded gauge

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so this fee makes it pricey to add more and more new denoms to the gauge

params := server.keeper.GetParams(ctx)
fee := params.AddToGaugeBaseFee.Add(params.AddDenomFee.MulRaw(int64(len(msg.Rewards) + len(gauge.Coins))))
if err = server.keeper.chargeFeeIfSufficientFeeDenomBalance(ctx, owner, fee, msg.Rewards); err != nil {
return nil, err
}
err = server.keeper.AddToGaugeRewards(ctx, owner, msg.Rewards, msg.GaugeId)

err = server.keeper.AddToGaugeRewards(ctx, owner, msg.Rewards, gauge)
if err != nil {
return nil, sdkerrors.Wrap(sdkerrors.ErrInvalidRequest, err.Error())
}
Expand Down
Loading
Loading