mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-11-04 09:47:28 +00:00 
			
		
		
		
	[R4R] fix: match reward payouts to current harvest v1 payouts (#786)
* fix: payout rewards on 1st or 15th of month * backport payout test * fix: add default case
This commit is contained in:
		
							parent
							
								
									37be34b4d6
								
							
						
					
					
						commit
						6118876074
					
				@ -1,6 +1,8 @@
 | 
			
		||||
package keeper
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	sdk "github.com/cosmos/cosmos-sdk/types"
 | 
			
		||||
	sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
 | 
			
		||||
	"github.com/cosmos/cosmos-sdk/x/auth"
 | 
			
		||||
@ -12,6 +14,15 @@ import (
 | 
			
		||||
	validatorvesting "github.com/kava-labs/kava/x/validator-vesting"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
const (
 | 
			
		||||
	// BeginningOfMonth harvest rewards that are claimed after the 15th at 14:00UTC of the month always vest on the first of the month
 | 
			
		||||
	BeginningOfMonth = 1
 | 
			
		||||
	// MidMonth harvest rewards that are claimed before the 15th at 14:00UTC of the month always vest on the 15 of the month
 | 
			
		||||
	MidMonth = 15
 | 
			
		||||
	// PaymentHour harvest rewards always vest at 14:00UTC
 | 
			
		||||
	PaymentHour = 14
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// ClaimUSDXMintingReward sends the reward amount to the input address and zero's out the claim in the store
 | 
			
		||||
func (k Keeper) ClaimUSDXMintingReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName types.MultiplierName) error {
 | 
			
		||||
	claim, found := k.GetUSDXMintingClaim(ctx, addr)
 | 
			
		||||
@ -40,7 +51,10 @@ func (k Keeper) ClaimUSDXMintingReward(ctx sdk.Context, addr sdk.AccAddress, mul
 | 
			
		||||
		return types.ErrZeroClaim
 | 
			
		||||
	}
 | 
			
		||||
	rewardCoin := sdk.NewCoin(claim.Reward.Denom, rewardAmount)
 | 
			
		||||
	length := ctx.BlockTime().AddDate(0, int(multiplier.MonthsLockup), 0).Unix() - ctx.BlockTime().Unix()
 | 
			
		||||
	length, err := k.GetPeriodLength(ctx, multiplier)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, addr, sdk.NewCoins(rewardCoin), length)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
@ -93,9 +107,12 @@ func (k Keeper) ClaimHardReward(ctx sdk.Context, addr sdk.AccAddress, multiplier
 | 
			
		||||
		}
 | 
			
		||||
		rewardCoins = append(rewardCoins, sdk.NewCoin(coin.Denom, rewardAmount))
 | 
			
		||||
	}
 | 
			
		||||
	length := ctx.BlockTime().AddDate(0, int(multiplier.MonthsLockup), 0).Unix() - ctx.BlockTime().Unix()
 | 
			
		||||
	length, err := k.GetPeriodLength(ctx, multiplier)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err := k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, addr, rewardCoins, length)
 | 
			
		||||
	err = k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, addr, rewardCoins, length)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
@ -170,6 +187,29 @@ func (k Keeper) SendTimeLockedCoinsToBaseAccount(ctx sdk.Context, senderModule s
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GetPeriodLength returns the length of the period based on the input blocktime and multiplier
 | 
			
		||||
// note that pay dates are always the 1st or 15th of the month at 14:00UTC.
 | 
			
		||||
func (k Keeper) GetPeriodLength(ctx sdk.Context, multiplier types.Multiplier) (int64, error) {
 | 
			
		||||
 | 
			
		||||
	if multiplier.MonthsLockup == 0 {
 | 
			
		||||
		return 0, nil
 | 
			
		||||
	}
 | 
			
		||||
	switch multiplier.Name {
 | 
			
		||||
	case types.Small, types.Medium, types.Large:
 | 
			
		||||
		currentDay := ctx.BlockTime().Day()
 | 
			
		||||
		payDay := BeginningOfMonth
 | 
			
		||||
		monthOffset := int64(1)
 | 
			
		||||
		if currentDay < MidMonth || (currentDay == MidMonth && ctx.BlockTime().Hour() < PaymentHour) {
 | 
			
		||||
			payDay = MidMonth
 | 
			
		||||
			monthOffset = int64(0)
 | 
			
		||||
		}
 | 
			
		||||
		periodEndDate := time.Date(ctx.BlockTime().Year(), ctx.BlockTime().Month(), payDay, PaymentHour, 0, 0, 0, time.UTC).AddDate(0, int(multiplier.MonthsLockup+monthOffset), 0)
 | 
			
		||||
		return periodEndDate.Unix() - ctx.BlockTime().Unix(), nil
 | 
			
		||||
	default:
 | 
			
		||||
		return 0, types.ErrInvalidMultiplier
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// addCoinsToVestingSchedule adds coins to the input account's vesting schedule where length is the amount of time (from the current block time), in seconds, that the coins will be vesting for
 | 
			
		||||
// the input address must be a periodic vesting account
 | 
			
		||||
func (k Keeper) addCoinsToVestingSchedule(ctx sdk.Context, addr sdk.AccAddress, amt sdk.Coins, length int64) {
 | 
			
		||||
 | 
			
		||||
@ -2,7 +2,6 @@ package keeper_test
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"errors"
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"strings"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
@ -55,7 +54,7 @@ func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaim() {
 | 
			
		||||
				multiplier:               types.MultiplierName("large"),
 | 
			
		||||
				timeElapsed:              86400,
 | 
			
		||||
				expectedBalance:          cs(c("usdx", 10000000000), c("ukava", 10576385600)),
 | 
			
		||||
				expectedPeriods:          vesting.Periods{vesting.Period{Length: 31536000, Amount: cs(c("ukava", 10571385600))}},
 | 
			
		||||
				expectedPeriods:          vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("ukava", 10571385600))}},
 | 
			
		||||
				isPeriodicVestingAccount: true,
 | 
			
		||||
			},
 | 
			
		||||
			errArgs{
 | 
			
		||||
@ -144,7 +143,6 @@ func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaim() {
 | 
			
		||||
				}
 | 
			
		||||
 | 
			
		||||
				claim, found := suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[0])
 | 
			
		||||
				fmt.Println(claim)
 | 
			
		||||
				suite.Require().True(found)
 | 
			
		||||
				suite.Require().Equal(c("ukava", 0), claim.Reward)
 | 
			
		||||
			} else {
 | 
			
		||||
@ -678,3 +676,142 @@ func (suite *KeeperTestSuite) SetupWithAccountState() {
 | 
			
		||||
	suite.ctx = ctx
 | 
			
		||||
	suite.addrs = addrs
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func (suite *KeeperTestSuite) TestGetPeriodLength() {
 | 
			
		||||
	type args struct {
 | 
			
		||||
		blockTime      time.Time
 | 
			
		||||
		multiplier     types.Multiplier
 | 
			
		||||
		expectedLength int64
 | 
			
		||||
	}
 | 
			
		||||
	type errArgs struct {
 | 
			
		||||
		expectPass bool
 | 
			
		||||
		contains   string
 | 
			
		||||
	}
 | 
			
		||||
	type periodTest struct {
 | 
			
		||||
		name    string
 | 
			
		||||
		args    args
 | 
			
		||||
		errArgs errArgs
 | 
			
		||||
	}
 | 
			
		||||
	testCases := []periodTest{
 | 
			
		||||
		{
 | 
			
		||||
			name: "first half of month",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 11, 2, 15, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2021, 5, 15, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 11, 2, 15, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "first half of month long lockup",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 11, 2, 15, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Medium, 24, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2022, 11, 15, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 11, 2, 15, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "second half of month",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 12, 31, 15, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2021, 7, 1, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 12, 31, 15, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "second half of month long lockup",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 12, 31, 15, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Large, 24, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2023, 1, 1, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 12, 31, 15, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "end of feb",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2021, 2, 28, 15, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2021, 9, 1, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2021, 2, 28, 15, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "leap year",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 2, 29, 15, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2020, 9, 1, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 2, 29, 15, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "leap year long lockup",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 2, 29, 15, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Large, 24, sdk.MustNewDecFromStr("1")),
 | 
			
		||||
				expectedLength: time.Date(2022, 3, 1, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 2, 29, 15, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "exactly half of month",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2021, 7, 1, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
		{
 | 
			
		||||
			name: "just before half of month",
 | 
			
		||||
			args: args{
 | 
			
		||||
				blockTime:      time.Date(2020, 12, 15, 13, 59, 59, 0, time.UTC),
 | 
			
		||||
				multiplier:     types.NewMultiplier(types.Medium, 6, sdk.MustNewDecFromStr("0.333333")),
 | 
			
		||||
				expectedLength: time.Date(2021, 6, 15, 14, 0, 0, 0, time.UTC).Unix() - time.Date(2020, 12, 15, 13, 59, 59, 0, time.UTC).Unix(),
 | 
			
		||||
			},
 | 
			
		||||
			errArgs: errArgs{
 | 
			
		||||
				expectPass: true,
 | 
			
		||||
				contains:   "",
 | 
			
		||||
			},
 | 
			
		||||
		},
 | 
			
		||||
	}
 | 
			
		||||
	for _, tc := range testCases {
 | 
			
		||||
		suite.Run(tc.name, func() {
 | 
			
		||||
			ctx := suite.ctx.WithBlockTime(tc.args.blockTime)
 | 
			
		||||
			length, err := suite.keeper.GetPeriodLength(ctx, tc.args.multiplier)
 | 
			
		||||
			if tc.errArgs.expectPass {
 | 
			
		||||
				suite.Require().NoError(err)
 | 
			
		||||
				suite.Require().Equal(tc.args.expectedLength, length)
 | 
			
		||||
			} else {
 | 
			
		||||
				suite.Require().Error(err)
 | 
			
		||||
			}
 | 
			
		||||
		})
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user