mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-26 00:05:18 +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