Skip to content

Commit

Permalink
feat(dividends): msg server and epoch hooks
Browse files Browse the repository at this point in the history
  • Loading branch information
keruch committed Jan 31, 2025
1 parent 288323b commit 6b9867e
Show file tree
Hide file tree
Showing 26 changed files with 534 additions and 2,546 deletions.
52 changes: 27 additions & 25 deletions proto/dividends/gauge.proto
Original file line number Diff line number Diff line change
Expand Up @@ -17,50 +17,52 @@ message Gauge {
string address = 2;
// query_condition is *where* the gauge rewards are distributed to
QueryCondition query_condition = 3;
// vesting_condition is *when* the gauge rewards are distributed to
// vesting_condition is *how long* the gauge rewards are distributed to
VestingCondition vesting_condition = 4;
// vesting_condition is *how frequent* the gauge rewards are distributed to
VestingFrequency vesting_frequency = 5;
}

message QueryCondition {
oneof condition {
QueryConditionStakers stakers = 1;
QueryConditionFunds funds = 2;
}
}

message VestingCondition {
oneof condition {
VestingConditionImmediate immediate = 1;
VestingConditionEpoch epoch = 2;
VestingConditionPerpetual perpetual = 1;
VestingConditionLimited epoch = 2;
}
}

enum VestingFrequency {
VESTING_FREQUENCY_UNSPECIFIED = 0;
VESTING_FREQUENCY_BLOCK = 1;
VESTING_FREQUENCY_EPOCH = 2;
}

// QueryConditionStakers queries the stakers
message QueryConditionStakers {}

// QueryConditionFunds queries the users with funds above a certain threshold
message QueryConditionFunds {
repeated cosmos.base.v1beta1.Coin threshold = 8 [
(gogoproto.nullable) = false,
(gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins"
];
}

// VestingConditionImmediate is a vesting condition that distributes rewards
// immediately. This gauge is perpetual by default.
// Non-perpetual gauges distribute their tokens equally per epoch while the
// VestingConditionPerpetual is a vesting condition that distributes rewards
// infinitely. Perpetual gauges distribute all their tokens at a single time
// and only distribute their tokens again once the gauge is refilled.
//
// Non-perpetual gauges distribute their tokens equally per period while the
// gauge is in the active period. Perpetual gauges distribute all their tokens
// at a single time and only distribute their tokens again once the gauge is
// refilled, Intended for use with incentives that get refilled daily.
message VestingConditionImmediate {}
// refilled.
message VestingConditionPerpetual {}

// VestingConditionEpoch is a vesting condition that distributes rewards over
// epochs
message VestingConditionEpoch {
// num_epochs_paid_over is the number of total epochs distribution will be
// VestingConditionLimited is a vesting condition that distributes rewards over
// the specified time. Non-perpetual gauges distribute their tokens equally per
// period while the gauge is in the active period.
message VestingConditionLimited {
// num_units is the number of total epochs/blocks distribution will be
// completed over
uint64 num_epochs_paid_over = 1;
// filled_epochs is the number of epochs distribution has been completed on
// already
uint64 filled_epochs = 2;
uint64 num_units = 1;
// filled_epochs is the number of epochs/blocks distribution has been
// completed on already
uint64 filled_units = 2;
}
4 changes: 3 additions & 1 deletion proto/dividends/tx.proto
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,10 @@ message MsgCreateGauge {
string address = 2;
// query_condition is *where* the gauge rewards are distributed to
QueryCondition query_condition = 3;
// vesting_condition is *when* the gauge rewards are distributed to
// vesting_condition is *how long* the gauge rewards are distributed to
VestingCondition vesting_condition = 4;
// vesting_condition is *how frequent* the gauge rewards are distributed to
VestingFrequency vesting_frequency = 5;
}

message MsgCreateGaugeResponse {}
54 changes: 54 additions & 0 deletions x/dividends/keeper/allocation.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package keeper

import (
"fmt"

sdk "github.com/cosmos/cosmos-sdk/types"
stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
"github.com/dymensionxyz/dymension-rdk/x/dividends/types"
)

func (k Keeper) Allocate(ctx sdk.Context) error {
var (
totalStakingPower = k.stakingKeeper.GetLastTotalPower(ctx)
totalStakingPowerDec = sdk.NewDecFromInt(totalStakingPower)
)

err := k.IterateGauges(ctx, func(_ uint64, gauge types.Gauge) (stop bool, err error) {
var (
address = sdk.MustAccAddressFromBech32(gauge.Address)
gaugeRewards = sdk.NewDecCoinsFromCoins(k.bankKeeper.GetAllBalances(ctx, address)...)
)

switch gauge.VestingCondition.Condition.(type) {
case *types.VestingCondition_Block:

Check failure on line 24 in x/dividends/keeper/allocation.go

View workflow job for this annotation

GitHub Actions / lint

undefined: types.VestingCondition_Block

Check failure on line 24 in x/dividends/keeper/allocation.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: types.VestingCondition_Block
case *types.VestingCondition_Epoch:
}

switch gauge.QueryCondition.Condition.(type) {
case *types.QueryCondition_Stakers:
k.AllocateStakers(ctx, totalStakingPowerDec, gaugeRewards)
case *types.QueryCondition_Funds:

Check failure on line 31 in x/dividends/keeper/allocation.go

View workflow job for this annotation

GitHub Actions / lint

undefined: types.QueryCondition_Funds

Check failure on line 31 in x/dividends/keeper/allocation.go

View workflow job for this annotation

GitHub Actions / golangci-lint

undefined: types.QueryCondition_Funds
}

return false, nil
})
if err != nil {
return fmt.Errorf("iterate gauges: %w", err)
}

return nil
}

func (k Keeper) AllocateStakers(ctx sdk.Context, stakingPower sdk.Dec, gaugeRewards sdk.DecCoins) {
k.stakingKeeper.IterateBondedValidatorsByPower(ctx, func(index int64, validator stakingtypes.ValidatorI) (stop bool) {
var (
valPower = validator.GetConsensusPower(sdk.DefaultPowerReduction)
powerFraction = sdk.NewDec(valPower).QuoTruncate(stakingPower)
reward = gaugeRewards.MulDecTruncate(powerFraction)
)

k.distrKeeper.AllocateTokensToValidator(ctx, validator, reward)
return false
})
}
141 changes: 0 additions & 141 deletions x/dividends/keeper/distribute.go

This file was deleted.

Loading

0 comments on commit 6b9867e

Please sign in to comment.