Skip to content

Commit

Permalink
feat(sponsorship): only allow sponsoring rollapps with bonded sequencers
Browse files Browse the repository at this point in the history
  • Loading branch information
keruch committed Sep 30, 2024
1 parent a028ec2 commit 5671869
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 21 deletions.
15 changes: 9 additions & 6 deletions x/sponsorship/keeper/keeper.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type Keeper struct {

stakingKeeper types.StakingKeeper
incentivesKeeper types.IncentivesKeeper
sequencerKeeper types.SequencerKeeper
}

// NewKeeper returns a new instance of the x/sponsorship keeper.
Expand All @@ -32,6 +33,7 @@ func NewKeeper(
ak types.AccountKeeper,
sk types.StakingKeeper,
ik types.IncentivesKeeper,
sqk types.SequencerKeeper,
authority string,
) Keeper {
// ensure the module account is set
Expand All @@ -53,12 +55,6 @@ func NewKeeper(
"params",
collcompat.ProtoValue[types.Params](cdc),
),
distribution: collections.NewItem(
sb,
types.DistributionPrefix(),
"distribution",
collcompat.ProtoValue[types.Distribution](cdc),
),
delegatorValidatorPower: collections.NewMap(
sb,
types.DelegatorValidatorPrefix(),
Expand All @@ -69,6 +65,12 @@ func NewKeeper(
),
collcompat.IntValue,
),
distribution: collections.NewItem(
sb,
types.DistributionPrefix(),
"distribution",
collcompat.ProtoValue[types.Distribution](cdc),
),
votes: collections.NewMap(
sb,
types.VotePrefix(),
Expand All @@ -78,5 +80,6 @@ func NewKeeper(
),
stakingKeeper: sk,
incentivesKeeper: ik,
sequencerKeeper: sqk,
}
}
56 changes: 41 additions & 15 deletions x/sponsorship/keeper/votes.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,32 +7,36 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

incentivestypes "github.com/dymensionxyz/dymension/v3/x/incentives/types"
sequencertypes "github.com/dymensionxyz/dymension/v3/x/sequencer/types"
"github.com/dymensionxyz/dymension/v3/x/sponsorship/types"
)

func (k Keeper) Vote(ctx sdk.Context, voter sdk.AccAddress, weights []types.GaugeWeight) (types.Vote, types.Distribution, error) {
// Get module params
params, err := k.GetParams(ctx)
if err != nil {
return types.Vote{}, types.Distribution{}, fmt.Errorf("cannot get module params: %w", err)
}

// Validate specified weights
err = k.validateWeights(ctx, weights, params.MinAllocationWeight)
if err != nil {
return types.Vote{}, types.Distribution{}, fmt.Errorf("error validating weights: %w", err)
}

// Check if the user's voted. If they have, revoke the previous vote to place a new one.
voted, err := k.Voted(ctx, voter)
if err != nil {
return types.Vote{}, types.Distribution{}, fmt.Errorf("cannot verify if the voter has already voted: %w", err)
}

if voted {
_, err := k.RevokeVote(ctx, voter)
if err != nil {
return types.Vote{}, types.Distribution{}, fmt.Errorf("failed to revoke previous vote: %w", err)
}
}

params, err := k.GetParams(ctx)
if err != nil {
return types.Vote{}, types.Distribution{}, fmt.Errorf("cannot get module params: %w", err)
}

err = k.validateWeights(ctx, weights, params.MinAllocationWeight)
if err != nil {
return types.Vote{}, types.Distribution{}, fmt.Errorf("error validating weights: %w", err)
}

// Get the user’s total voting power from the x/staking
vpBreakdown, err := k.GetValidatorBreakdown(ctx, voter)
if err != nil {
Expand Down Expand Up @@ -107,21 +111,43 @@ func (k Keeper) revokeVote(ctx sdk.Context, voter sdk.AccAddress, vote types.Vot
return d, nil
}

// validateWeights validates that no gauge got less than MinAllocationWeight and all of them are perpetual
// validateWeights validates that
// - No gauge get less than MinAllocationWeight
// - All gauges exist
// - All gauges are perpetual
// - Rollapp gauges have at least one bonded sequencer
func (k Keeper) validateWeights(ctx sdk.Context, weights []types.GaugeWeight, minAllocationWeight math.Int) error {
for _, weight := range weights {
// No gauge get less than MinAllocationWeight
if weight.Weight.LT(minAllocationWeight) {
return fmt.Errorf("gauge weight '%s' is less than min allocation weight '%s'", weight.Weight, minAllocationWeight)
return fmt.Errorf("gauge weight is less than min allocation weight: gauge weight %s, min allocation %s", weight.Weight, minAllocationWeight)
}

// All gauges exist
gauge, err := k.incentivesKeeper.GetGaugeByID(ctx, weight.GaugeId)
if err != nil {
return fmt.Errorf("failed to get gauge by id '%d': %w", weight.GaugeId, err)
return fmt.Errorf("failed to get gauge by id: %d: %w", weight.GaugeId, err)
}

// All gauges are perpetual
if !gauge.IsPerpetual {
return fmt.Errorf("gauge '%d' is not perpetual", weight.GaugeId)
return fmt.Errorf("gauge is not perpetual: %d", weight.GaugeId)
}

// Rollapp gauges have at least one bonded sequencer
switch distrTo := gauge.DistributeTo.(type) {
case *incentivestypes.Gauge_Asset:
// no additional restrictions for asset gauges
case *incentivestypes.Gauge_Rollapp:
// we allow sponsoring only rollapps with bonded sequencers
bondedSequencers := k.sequencerKeeper.GetSequencersByRollappByStatus(ctx, distrTo.Rollapp.RollappId, sequencertypes.Bonded)
if len(bondedSequencers) == 0 {
return fmt.Errorf("rollapp has no bonded sequencers: %s'", distrTo.Rollapp.RollappId)
}
default:
return fmt.Errorf("gauge has an unsupported distribution type: gauge id %d, type %T", gauge.Id, distrTo)
}

}
return nil
}
Expand Down
5 changes: 5 additions & 0 deletions x/sponsorship/types/expected_keepers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"

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

// AccountKeeper defines the contract required for account APIs.
Expand All @@ -21,3 +22,7 @@ type StakingKeeper interface {
type IncentivesKeeper interface {
GetGaugeByID(ctx sdk.Context, gaugeID uint64) (*incentivestypes.Gauge, error)
}

type SequencerKeeper interface {
GetSequencersByRollappByStatus(ctx sdk.Context, rollappId string, status sequencertypes.OperatingStatus) []sequencertypes.Sequencer
}

0 comments on commit 5671869

Please sign in to comment.