mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-24 23:35:19 +00:00
[R4R] re-enable claiming rewards validator vesting accounts (#920)
* feat: add new msg types for claim rewards from validator vesting accounts * fix: validate owner is validator vesting account * feat: add validator vesting tests for incent claims * address review comments * fix: client command name and example
This commit is contained in:
parent
fc85052522
commit
4d6f6aab3c
@ -1,154 +1,175 @@
|
|||||||
|
// nolint
|
||||||
|
// autogenerated code using github.com/rigelrozanski/multitool
|
||||||
|
// aliases generated for the following subdirectories:
|
||||||
|
// ALIASGEN: github.com/kava-labs/kava/x/incentive/types
|
||||||
|
// ALIASGEN: github.com/kava-labs/kava/x/incentive/keeper
|
||||||
package incentive
|
package incentive
|
||||||
|
|
||||||
// DO NOT EDIT - generated by aliasgen tool (github.com/rhuairahrighairidh/aliasgen)
|
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/kava-labs/kava/x/incentive/keeper"
|
"github.com/kava-labs/kava/x/incentive/keeper"
|
||||||
"github.com/kava-labs/kava/x/incentive/types"
|
"github.com/kava-labs/kava/x/incentive/types"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
BeginningOfMonth = keeper.BeginningOfMonth
|
USDXMintingClaimType = types.USDXMintingClaimType
|
||||||
MidMonth = keeper.MidMonth
|
HardLiquidityProviderClaimType = types.HardLiquidityProviderClaimType
|
||||||
PaymentHour = keeper.PaymentHour
|
|
||||||
AttributeKeyClaimAmount = types.AttributeKeyClaimAmount
|
|
||||||
AttributeKeyClaimPeriod = types.AttributeKeyClaimPeriod
|
|
||||||
AttributeKeyClaimType = types.AttributeKeyClaimType
|
|
||||||
AttributeKeyClaimedBy = types.AttributeKeyClaimedBy
|
|
||||||
AttributeKeyRewardPeriod = types.AttributeKeyRewardPeriod
|
|
||||||
AttributeValueCategory = types.AttributeValueCategory
|
|
||||||
BondDenom = types.BondDenom
|
BondDenom = types.BondDenom
|
||||||
DefaultParamspace = types.DefaultParamspace
|
|
||||||
EventTypeClaim = types.EventTypeClaim
|
EventTypeClaim = types.EventTypeClaim
|
||||||
|
EventTypeRewardPeriod = types.EventTypeRewardPeriod
|
||||||
EventTypeClaimPeriod = types.EventTypeClaimPeriod
|
EventTypeClaimPeriod = types.EventTypeClaimPeriod
|
||||||
EventTypeClaimPeriodExpiry = types.EventTypeClaimPeriodExpiry
|
EventTypeClaimPeriodExpiry = types.EventTypeClaimPeriodExpiry
|
||||||
EventTypeRewardPeriod = types.EventTypeRewardPeriod
|
AttributeValueCategory = types.AttributeValueCategory
|
||||||
HardLiquidityProviderClaimType = types.HardLiquidityProviderClaimType
|
AttributeKeyClaimedBy = types.AttributeKeyClaimedBy
|
||||||
Large = types.Large
|
AttributeKeyClaimAmount = types.AttributeKeyClaimAmount
|
||||||
Medium = types.Medium
|
AttributeKeyClaimType = types.AttributeKeyClaimType
|
||||||
|
AttributeKeyRewardPeriod = types.AttributeKeyRewardPeriod
|
||||||
|
AttributeKeyClaimPeriod = types.AttributeKeyClaimPeriod
|
||||||
ModuleName = types.ModuleName
|
ModuleName = types.ModuleName
|
||||||
|
StoreKey = types.StoreKey
|
||||||
|
RouterKey = types.RouterKey
|
||||||
|
DefaultParamspace = types.DefaultParamspace
|
||||||
QuerierRoute = types.QuerierRoute
|
QuerierRoute = types.QuerierRoute
|
||||||
QueryGetClaimPeriods = types.QueryGetClaimPeriods
|
Small = types.Small
|
||||||
|
Medium = types.Medium
|
||||||
|
Large = types.Large
|
||||||
|
QueryGetRewards = types.QueryGetRewards
|
||||||
QueryGetHardRewards = types.QueryGetHardRewards
|
QueryGetHardRewards = types.QueryGetHardRewards
|
||||||
|
QueryGetHardRewardsUnsynced = types.QueryGetHardRewardsUnsynced
|
||||||
|
QueryGetUSDXMintingRewards = types.QueryGetUSDXMintingRewards
|
||||||
|
QueryGetUSDXMintingRewardsUnsynced = types.QueryGetUSDXMintingRewardsUnsynced
|
||||||
|
QueryGetRewardFactors = types.QueryGetRewardFactors
|
||||||
QueryGetParams = types.QueryGetParams
|
QueryGetParams = types.QueryGetParams
|
||||||
QueryGetRewardPeriods = types.QueryGetRewardPeriods
|
QueryGetRewardPeriods = types.QueryGetRewardPeriods
|
||||||
QueryGetRewards = types.QueryGetRewards
|
QueryGetClaimPeriods = types.QueryGetClaimPeriods
|
||||||
QueryGetUSDXMintingRewards = types.QueryGetUSDXMintingRewards
|
|
||||||
RestClaimCollateralType = types.RestClaimCollateralType
|
RestClaimCollateralType = types.RestClaimCollateralType
|
||||||
RestClaimOwner = types.RestClaimOwner
|
RestClaimOwner = types.RestClaimOwner
|
||||||
RestClaimType = types.RestClaimType
|
RestClaimType = types.RestClaimType
|
||||||
RouterKey = types.RouterKey
|
RestUnsynced = types.RestUnsynced
|
||||||
Small = types.Small
|
BeginningOfMonth = keeper.BeginningOfMonth
|
||||||
StoreKey = types.StoreKey
|
MidMonth = keeper.MidMonth
|
||||||
USDXMintingClaimType = types.USDXMintingClaimType
|
PaymentHour = keeper.PaymentHour
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// function aliases
|
// functions aliases
|
||||||
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
|
||||||
NewKeeper = keeper.NewKeeper
|
|
||||||
NewQuerier = keeper.NewQuerier
|
|
||||||
DefaultGenesisState = types.DefaultGenesisState
|
|
||||||
DefaultParams = types.DefaultParams
|
|
||||||
GetTotalVestingPeriodLength = types.GetTotalVestingPeriodLength
|
GetTotalVestingPeriodLength = types.GetTotalVestingPeriodLength
|
||||||
NewGenesisAccumulationTime = types.NewGenesisAccumulationTime
|
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
||||||
NewGenesisState = types.NewGenesisState
|
|
||||||
NewHardLiquidityProviderClaim = types.NewHardLiquidityProviderClaim
|
NewHardLiquidityProviderClaim = types.NewHardLiquidityProviderClaim
|
||||||
NewMsgClaimHardReward = types.NewMsgClaimHardReward
|
|
||||||
NewMsgClaimUSDXMintingReward = types.NewMsgClaimUSDXMintingReward
|
|
||||||
NewMultiRewardIndex = types.NewMultiRewardIndex
|
|
||||||
NewMultiRewardPeriod = types.NewMultiRewardPeriod
|
NewMultiRewardPeriod = types.NewMultiRewardPeriod
|
||||||
NewMultiplier = types.NewMultiplier
|
NewRewardIndex = types.NewRewardIndex
|
||||||
|
NewMultiRewardIndex = types.NewMultiRewardIndex
|
||||||
|
RegisterCodec = types.RegisterCodec
|
||||||
|
NewGenesisState = types.NewGenesisState
|
||||||
|
DefaultGenesisState = types.DefaultGenesisState
|
||||||
|
NewGenesisAccumulationTime = types.NewGenesisAccumulationTime
|
||||||
|
NewMsgClaimUSDXMintingReward = types.NewMsgClaimUSDXMintingReward
|
||||||
|
NewMsgClaimUSDXMintingRewardVVesting = types.NewMsgClaimUSDXMintingRewardVVesting
|
||||||
|
NewMsgClaimHardReward = types.NewMsgClaimHardReward
|
||||||
|
NewMsgClaimHardRewardVVesting = types.NewMsgClaimHardRewardVVesting
|
||||||
NewParams = types.NewParams
|
NewParams = types.NewParams
|
||||||
|
DefaultParams = types.DefaultParams
|
||||||
|
ParamKeyTable = types.ParamKeyTable
|
||||||
|
NewRewardPeriod = types.NewRewardPeriod
|
||||||
|
NewMultiplier = types.NewMultiplier
|
||||||
NewPeriod = types.NewPeriod
|
NewPeriod = types.NewPeriod
|
||||||
NewQueryHardRewardsParams = types.NewQueryHardRewardsParams
|
|
||||||
NewQueryRewardsParams = types.NewQueryRewardsParams
|
NewQueryRewardsParams = types.NewQueryRewardsParams
|
||||||
NewQueryUSDXMintingRewardsParams = types.NewQueryUSDXMintingRewardsParams
|
NewQueryUSDXMintingRewardsParams = types.NewQueryUSDXMintingRewardsParams
|
||||||
NewRewardIndex = types.NewRewardIndex
|
NewQueryUSDXMintingRewardsUnsyncedParams = types.NewQueryUSDXMintingRewardsUnsyncedParams
|
||||||
NewRewardPeriod = types.NewRewardPeriod
|
NewQueryHardRewardsParams = types.NewQueryHardRewardsParams
|
||||||
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
NewQueryHardRewardsUnsyncedParams = types.NewQueryHardRewardsUnsyncedParams
|
||||||
ParamKeyTable = types.ParamKeyTable
|
NewQueryRewardFactorsParams = types.NewQueryRewardFactorsParams
|
||||||
RegisterCodec = types.RegisterCodec
|
NewRewardFactor = types.NewRewardFactor
|
||||||
|
NewKeeper = keeper.NewKeeper
|
||||||
|
NewQuerier = keeper.NewQuerier
|
||||||
|
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
||||||
|
|
||||||
// variable aliases
|
// variable aliases
|
||||||
DefaultActive = types.DefaultActive
|
ModuleCdc = types.ModuleCdc
|
||||||
DefaultClaimEnd = types.DefaultClaimEnd
|
|
||||||
DefaultGenesisAccumulationTimes = types.DefaultGenesisAccumulationTimes
|
|
||||||
DefaultHardClaims = types.DefaultHardClaims
|
|
||||||
DefaultMultiRewardPeriods = types.DefaultMultiRewardPeriods
|
|
||||||
DefaultMultipliers = types.DefaultMultipliers
|
|
||||||
DefaultRewardPeriods = types.DefaultRewardPeriods
|
|
||||||
DefaultUSDXClaims = types.DefaultUSDXClaims
|
|
||||||
ErrAccountNotFound = types.ErrAccountNotFound
|
|
||||||
ErrClaimExpired = types.ErrClaimExpired
|
|
||||||
ErrClaimNotFound = types.ErrClaimNotFound
|
ErrClaimNotFound = types.ErrClaimNotFound
|
||||||
ErrInsufficientModAccountBalance = types.ErrInsufficientModAccountBalance
|
|
||||||
ErrInvalidAccountType = types.ErrInvalidAccountType
|
|
||||||
ErrInvalidClaimType = types.ErrInvalidClaimType
|
|
||||||
ErrInvalidMultiplier = types.ErrInvalidMultiplier
|
|
||||||
ErrNoClaimsFound = types.ErrNoClaimsFound
|
|
||||||
ErrRewardPeriodNotFound = types.ErrRewardPeriodNotFound
|
ErrRewardPeriodNotFound = types.ErrRewardPeriodNotFound
|
||||||
|
ErrInvalidAccountType = types.ErrInvalidAccountType
|
||||||
|
ErrNoClaimsFound = types.ErrNoClaimsFound
|
||||||
|
ErrInsufficientModAccountBalance = types.ErrInsufficientModAccountBalance
|
||||||
|
ErrAccountNotFound = types.ErrAccountNotFound
|
||||||
|
ErrInvalidMultiplier = types.ErrInvalidMultiplier
|
||||||
ErrZeroClaim = types.ErrZeroClaim
|
ErrZeroClaim = types.ErrZeroClaim
|
||||||
GovDenom = types.GovDenom
|
ErrClaimExpired = types.ErrClaimExpired
|
||||||
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
ErrInvalidClaimType = types.ErrInvalidClaimType
|
||||||
HardDelegatorRewardFactorKeyPrefix = types.HardDelegatorRewardFactorKeyPrefix
|
ErrInvalidClaimOwner = types.ErrInvalidClaimOwner
|
||||||
|
USDXMintingClaimKeyPrefix = types.USDXMintingClaimKeyPrefix
|
||||||
|
USDXMintingRewardFactorKeyPrefix = types.USDXMintingRewardFactorKeyPrefix
|
||||||
|
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = types.PreviousUSDXMintingRewardAccrualTimeKeyPrefix
|
||||||
HardLiquidityClaimKeyPrefix = types.HardLiquidityClaimKeyPrefix
|
HardLiquidityClaimKeyPrefix = types.HardLiquidityClaimKeyPrefix
|
||||||
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
|
||||||
HardSupplyRewardIndexesKeyPrefix = types.HardSupplyRewardIndexesKeyPrefix
|
HardSupplyRewardIndexesKeyPrefix = types.HardSupplyRewardIndexesKeyPrefix
|
||||||
IncentiveMacc = types.IncentiveMacc
|
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
||||||
KeyClaimEnd = types.KeyClaimEnd
|
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
||||||
|
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
||||||
|
HardDelegatorRewardFactorKeyPrefix = types.HardDelegatorRewardFactorKeyPrefix
|
||||||
|
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = types.PreviousHardDelegatorRewardAccrualTimeKeyPrefix
|
||||||
|
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
||||||
|
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
||||||
|
KeyUSDXMintingRewardPeriods = types.KeyUSDXMintingRewardPeriods
|
||||||
|
KeyHardSupplyRewardPeriods = types.KeyHardSupplyRewardPeriods
|
||||||
KeyHardBorrowRewardPeriods = types.KeyHardBorrowRewardPeriods
|
KeyHardBorrowRewardPeriods = types.KeyHardBorrowRewardPeriods
|
||||||
KeyHardDelegatorRewardPeriods = types.KeyHardDelegatorRewardPeriods
|
KeyHardDelegatorRewardPeriods = types.KeyHardDelegatorRewardPeriods
|
||||||
KeyHardSupplyRewardPeriods = types.KeyHardSupplyRewardPeriods
|
KeyClaimEnd = types.KeyClaimEnd
|
||||||
KeyMultipliers = types.KeyMultipliers
|
KeyMultipliers = types.KeyMultipliers
|
||||||
KeyUSDXMintingRewardPeriods = types.KeyUSDXMintingRewardPeriods
|
DefaultActive = types.DefaultActive
|
||||||
ModuleCdc = types.ModuleCdc
|
DefaultRewardPeriods = types.DefaultRewardPeriods
|
||||||
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
DefaultMultiRewardPeriods = types.DefaultMultiRewardPeriods
|
||||||
PreviousHardDelegatorRewardAccrualTimeKeyPrefix = types.PreviousHardDelegatorRewardAccrualTimeKeyPrefix
|
DefaultMultipliers = types.DefaultMultipliers
|
||||||
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
DefaultUSDXClaims = types.DefaultUSDXClaims
|
||||||
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = types.PreviousUSDXMintingRewardAccrualTimeKeyPrefix
|
DefaultHardClaims = types.DefaultHardClaims
|
||||||
|
DefaultGenesisAccumulationTimes = types.DefaultGenesisAccumulationTimes
|
||||||
|
DefaultClaimEnd = types.DefaultClaimEnd
|
||||||
|
GovDenom = types.GovDenom
|
||||||
PrincipalDenom = types.PrincipalDenom
|
PrincipalDenom = types.PrincipalDenom
|
||||||
USDXMintingClaimKeyPrefix = types.USDXMintingClaimKeyPrefix
|
IncentiveMacc = types.IncentiveMacc
|
||||||
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
|
||||||
USDXMintingRewardFactorKeyPrefix = types.USDXMintingRewardFactorKeyPrefix
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
Hooks = keeper.Hooks
|
|
||||||
Keeper = keeper.Keeper
|
|
||||||
AccountKeeper = types.AccountKeeper
|
|
||||||
BaseClaim = types.BaseClaim
|
|
||||||
BaseMultiClaim = types.BaseMultiClaim
|
|
||||||
CDPHooks = types.CDPHooks
|
|
||||||
CdpKeeper = types.CdpKeeper
|
|
||||||
Claim = types.Claim
|
Claim = types.Claim
|
||||||
Claims = types.Claims
|
Claims = types.Claims
|
||||||
GenesisAccumulationTime = types.GenesisAccumulationTime
|
BaseClaim = types.BaseClaim
|
||||||
GenesisAccumulationTimes = types.GenesisAccumulationTimes
|
BaseMultiClaim = types.BaseMultiClaim
|
||||||
GenesisState = types.GenesisState
|
|
||||||
HARDHooks = types.HARDHooks
|
|
||||||
HardKeeper = types.HardKeeper
|
|
||||||
HardLiquidityProviderClaim = types.HardLiquidityProviderClaim
|
|
||||||
HardLiquidityProviderClaims = types.HardLiquidityProviderClaims
|
|
||||||
MsgClaimHardReward = types.MsgClaimHardReward
|
|
||||||
MsgClaimUSDXMintingReward = types.MsgClaimUSDXMintingReward
|
|
||||||
MultiRewardIndex = types.MultiRewardIndex
|
|
||||||
MultiRewardIndexes = types.MultiRewardIndexes
|
|
||||||
MultiRewardPeriod = types.MultiRewardPeriod
|
|
||||||
MultiRewardPeriods = types.MultiRewardPeriods
|
|
||||||
Multiplier = types.Multiplier
|
|
||||||
MultiplierName = types.MultiplierName
|
|
||||||
Multipliers = types.Multipliers
|
|
||||||
Params = types.Params
|
|
||||||
QueryHardRewardsParams = types.QueryHardRewardsParams
|
|
||||||
QueryRewardsParams = types.QueryRewardsParams
|
|
||||||
QueryUSDXMintingRewardsParams = types.QueryUSDXMintingRewardsParams
|
|
||||||
RewardIndex = types.RewardIndex
|
|
||||||
RewardIndexes = types.RewardIndexes
|
|
||||||
RewardPeriod = types.RewardPeriod
|
|
||||||
RewardPeriods = types.RewardPeriods
|
|
||||||
StakingKeeper = types.StakingKeeper
|
|
||||||
SupplyKeeper = types.SupplyKeeper
|
|
||||||
USDXMintingClaim = types.USDXMintingClaim
|
USDXMintingClaim = types.USDXMintingClaim
|
||||||
USDXMintingClaims = types.USDXMintingClaims
|
USDXMintingClaims = types.USDXMintingClaims
|
||||||
|
HardLiquidityProviderClaim = types.HardLiquidityProviderClaim
|
||||||
|
HardLiquidityProviderClaims = types.HardLiquidityProviderClaims
|
||||||
|
MultiRewardPeriod = types.MultiRewardPeriod
|
||||||
|
MultiRewardPeriods = types.MultiRewardPeriods
|
||||||
|
RewardIndex = types.RewardIndex
|
||||||
|
RewardIndexes = types.RewardIndexes
|
||||||
|
MultiRewardIndex = types.MultiRewardIndex
|
||||||
|
MultiRewardIndexes = types.MultiRewardIndexes
|
||||||
|
SupplyKeeper = types.SupplyKeeper
|
||||||
|
StakingKeeper = types.StakingKeeper
|
||||||
|
CdpKeeper = types.CdpKeeper
|
||||||
|
HardKeeper = types.HardKeeper
|
||||||
|
AccountKeeper = types.AccountKeeper
|
||||||
|
CDPHooks = types.CDPHooks
|
||||||
|
HARDHooks = types.HARDHooks
|
||||||
|
GenesisState = types.GenesisState
|
||||||
|
GenesisAccumulationTime = types.GenesisAccumulationTime
|
||||||
|
GenesisAccumulationTimes = types.GenesisAccumulationTimes
|
||||||
|
MsgClaimUSDXMintingReward = types.MsgClaimUSDXMintingReward
|
||||||
|
MsgClaimUSDXMintingRewardVVesting = types.MsgClaimUSDXMintingRewardVVesting
|
||||||
|
MsgClaimHardReward = types.MsgClaimHardReward
|
||||||
|
MsgClaimHardRewardVVesting = types.MsgClaimHardRewardVVesting
|
||||||
|
Params = types.Params
|
||||||
|
RewardPeriod = types.RewardPeriod
|
||||||
|
RewardPeriods = types.RewardPeriods
|
||||||
|
Multiplier = types.Multiplier
|
||||||
|
Multipliers = types.Multipliers
|
||||||
|
MultiplierName = types.MultiplierName
|
||||||
|
QueryRewardsParams = types.QueryRewardsParams
|
||||||
|
QueryUSDXMintingRewardsParams = types.QueryUSDXMintingRewardsParams
|
||||||
|
QueryUSDXMintingRewardsUnsyncedParams = types.QueryUSDXMintingRewardsUnsyncedParams
|
||||||
|
QueryHardRewardsParams = types.QueryHardRewardsParams
|
||||||
|
QueryHardRewardsUnsyncedParams = types.QueryHardRewardsUnsyncedParams
|
||||||
|
QueryRewardFactorsParams = types.QueryRewardFactorsParams
|
||||||
|
RewardFactor = types.RewardFactor
|
||||||
|
RewardFactors = types.RewardFactors
|
||||||
|
Hooks = keeper.Hooks
|
||||||
|
Keeper = keeper.Keeper
|
||||||
)
|
)
|
||||||
|
@ -27,7 +27,9 @@ func GetTxCmd(cdc *codec.Codec) *cobra.Command {
|
|||||||
|
|
||||||
incentiveTxCmd.AddCommand(flags.PostCommands(
|
incentiveTxCmd.AddCommand(flags.PostCommands(
|
||||||
getCmdClaimCdp(cdc),
|
getCmdClaimCdp(cdc),
|
||||||
|
getCmdClaimCdpVVesting(cdc),
|
||||||
getCmdClaimHard(cdc),
|
getCmdClaimHard(cdc),
|
||||||
|
getCmdClaimHardVVesting(cdc),
|
||||||
)...)
|
)...)
|
||||||
|
|
||||||
return incentiveTxCmd
|
return incentiveTxCmd
|
||||||
@ -63,6 +65,76 @@ func getCmdClaimCdp(cdc *codec.Codec) *cobra.Command {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getCmdClaimCdpVVesting(cdc *codec.Codec) *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "claim-cdp-vesting [multiplier] [receiver]",
|
||||||
|
Short: "claim CDP rewards using a given multiplier on behalf of a validator vesting account",
|
||||||
|
Long: strings.TrimSpace(
|
||||||
|
fmt.Sprintf(`Claim sender's outstanding CDP rewards on behalf of a validator vesting using a given multiplier
|
||||||
|
|
||||||
|
Example:
|
||||||
|
$ %s tx %s claim-cdp-vesting large kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||||
|
`, version.ClientName, types.ModuleName),
|
||||||
|
),
|
||||||
|
Args: cobra.ExactArgs(2),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||||
|
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||||
|
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
|
||||||
|
|
||||||
|
sender := cliCtx.GetFromAddress()
|
||||||
|
multiplier := args[0]
|
||||||
|
receiverStr := args[1]
|
||||||
|
receiver, err := sdk.AccAddressFromBech32(receiverStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := types.NewMsgClaimUSDXMintingRewardVVesting(sender, receiver, multiplier)
|
||||||
|
err = msg.ValidateBasic()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func getCmdClaimHardVVesting(cdc *codec.Codec) *cobra.Command {
|
||||||
|
return &cobra.Command{
|
||||||
|
Use: "claim-hard-vesting [multiplier] [receiver]",
|
||||||
|
Short: "claim Hard module rewards on behalf of a validator vesting account using a given multiplier",
|
||||||
|
Long: strings.TrimSpace(
|
||||||
|
fmt.Sprintf(`Claim sender's outstanding Hard rewards on behalf of a validator vesting account for deposit/borrow/delegate using given multiplier
|
||||||
|
|
||||||
|
Example:
|
||||||
|
$ %s tx %s claim-hard-vesting large kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||||
|
`, version.ClientName, types.ModuleName),
|
||||||
|
),
|
||||||
|
Args: cobra.ExactArgs(2),
|
||||||
|
RunE: func(cmd *cobra.Command, args []string) error {
|
||||||
|
inBuf := bufio.NewReader(cmd.InOrStdin())
|
||||||
|
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||||
|
txBldr := auth.NewTxBuilderFromCLI(inBuf).WithTxEncoder(utils.GetTxEncoder(cdc))
|
||||||
|
|
||||||
|
sender := cliCtx.GetFromAddress()
|
||||||
|
multiplier := args[0]
|
||||||
|
receiverStr := args[1]
|
||||||
|
receiver, err := sdk.AccAddressFromBech32(receiverStr)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := types.NewMsgClaimHardRewardVVesting(sender, receiver, multiplier)
|
||||||
|
err = msg.ValidateBasic()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return utils.GenerateOrBroadcastMsgs(cliCtx, txBldr, []sdk.Msg{msg})
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func getCmdClaimHard(cdc *codec.Codec) *cobra.Command {
|
func getCmdClaimHard(cdc *codec.Codec) *cobra.Command {
|
||||||
return &cobra.Command{
|
return &cobra.Command{
|
||||||
Use: "claim-hard [multiplier]",
|
Use: "claim-hard [multiplier]",
|
||||||
|
@ -26,3 +26,11 @@ type PostClaimReq struct {
|
|||||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||||
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// PostClaimReq defines the properties of claim transaction's request body.
|
||||||
|
type PostClaimVVestingReq struct {
|
||||||
|
BaseReq rest.BaseReq `json:"base_req" yaml:"base_req"`
|
||||||
|
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||||
|
Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"`
|
||||||
|
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||||
|
}
|
||||||
|
@ -17,7 +17,10 @@ import (
|
|||||||
|
|
||||||
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
func registerTxRoutes(cliCtx context.CLIContext, r *mux.Router) {
|
||||||
r.HandleFunc("/incentive/claim-cdp", postClaimCdpHandlerFn(cliCtx)).Methods("POST")
|
r.HandleFunc("/incentive/claim-cdp", postClaimCdpHandlerFn(cliCtx)).Methods("POST")
|
||||||
|
r.HandleFunc("/incentive/claim-cdp-vesting", postClaimCdpVVestingHandlerFn(cliCtx)).Methods("POST")
|
||||||
r.HandleFunc("/incentive/claim-hard", postClaimHardHandlerFn(cliCtx)).Methods("POST")
|
r.HandleFunc("/incentive/claim-hard", postClaimHardHandlerFn(cliCtx)).Methods("POST")
|
||||||
|
r.HandleFunc("/incentive/claim-hard-vesting", postClaimHardVVestingHandlerFn(cliCtx)).Methods("POST")
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||||
@ -53,6 +56,39 @@ func postClaimCdpHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func postClaimCdpVVestingHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var requestBody PostClaimVVestingReq
|
||||||
|
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
requestBody.BaseReq = requestBody.BaseReq.Sanitize()
|
||||||
|
if !requestBody.BaseReq.ValidateBasic(w) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fromAddr, err := sdk.AccAddressFromBech32(requestBody.BaseReq.From)
|
||||||
|
if err != nil {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(fromAddr, requestBody.Sender) {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("expected: %s, got: %s", fromAddr, requestBody.Sender))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := types.NewMsgClaimUSDXMintingRewardVVesting(requestBody.Sender, requestBody.Receiver, requestBody.MultiplierName)
|
||||||
|
if err := msg.ValidateBasic(); err != nil {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.WriteGenerateStdTxResponse(w, cliCtx, requestBody.BaseReq, []sdk.Msg{msg})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func postClaimHardHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
func postClaimHardHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||||
return func(w http.ResponseWriter, r *http.Request) {
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
var requestBody PostClaimReq
|
var requestBody PostClaimReq
|
||||||
@ -85,3 +121,36 @@ func postClaimHardHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
|||||||
utils.WriteGenerateStdTxResponse(w, cliCtx, requestBody.BaseReq, []sdk.Msg{msg})
|
utils.WriteGenerateStdTxResponse(w, cliCtx, requestBody.BaseReq, []sdk.Msg{msg})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func postClaimHardVVestingHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||||
|
return func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
var requestBody PostClaimVVestingReq
|
||||||
|
if !rest.ReadRESTReq(w, r, cliCtx.Codec, &requestBody) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
requestBody.BaseReq = requestBody.BaseReq.Sanitize()
|
||||||
|
if !requestBody.BaseReq.ValidateBasic(w) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fromAddr, err := sdk.AccAddressFromBech32(requestBody.BaseReq.From)
|
||||||
|
if err != nil {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if !bytes.Equal(fromAddr, requestBody.Sender) {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusUnauthorized, fmt.Sprintf("expected: %s, got: %s", fromAddr, requestBody.Sender))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
msg := types.NewMsgClaimHardRewardVVesting(requestBody.Sender, requestBody.Receiver, requestBody.MultiplierName)
|
||||||
|
if err := msg.ValidateBasic(); err != nil {
|
||||||
|
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
utils.WriteGenerateStdTxResponse(w, cliCtx, requestBody.BaseReq, []sdk.Msg{msg})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -15,8 +15,12 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
|||||||
switch msg := msg.(type) {
|
switch msg := msg.(type) {
|
||||||
case types.MsgClaimUSDXMintingReward:
|
case types.MsgClaimUSDXMintingReward:
|
||||||
return handleMsgClaimUSDXMintingReward(ctx, k, msg)
|
return handleMsgClaimUSDXMintingReward(ctx, k, msg)
|
||||||
|
case types.MsgClaimUSDXMintingRewardVVesting:
|
||||||
|
return handleMsgClaimUSDXMintingRewardVVesting(ctx, k, msg)
|
||||||
case types.MsgClaimHardReward:
|
case types.MsgClaimHardReward:
|
||||||
return handleMsgClaimHardReward(ctx, k, msg)
|
return handleMsgClaimHardReward(ctx, k, msg)
|
||||||
|
case types.MsgClaimHardRewardVVesting:
|
||||||
|
return handleMsgClaimHardRewardVVesting(ctx, k, msg)
|
||||||
default:
|
default:
|
||||||
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
|
return nil, sdkerrors.Wrapf(sdkerrors.ErrUnknownRequest, "unrecognized %s message type: %T", ModuleName, msg)
|
||||||
}
|
}
|
||||||
@ -24,7 +28,6 @@ func NewHandler(k keeper.Keeper) sdk.Handler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func handleMsgClaimUSDXMintingReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimUSDXMintingReward) (*sdk.Result, error) {
|
func handleMsgClaimUSDXMintingReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimUSDXMintingReward) (*sdk.Result, error) {
|
||||||
|
|
||||||
err := k.ClaimUSDXMintingReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
err := k.ClaimUSDXMintingReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -34,6 +37,17 @@ func handleMsgClaimUSDXMintingReward(ctx sdk.Context, k keeper.Keeper, msg types
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleMsgClaimUSDXMintingRewardVVesting(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimUSDXMintingRewardVVesting) (*sdk.Result, error) {
|
||||||
|
|
||||||
|
err := k.ClaimUSDXMintingRewardVVesting(ctx, msg.Sender, msg.Receiver, types.MultiplierName(msg.MultiplierName))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &sdk.Result{
|
||||||
|
Events: ctx.EventManager().Events(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func handleMsgClaimHardReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimHardReward) (*sdk.Result, error) {
|
func handleMsgClaimHardReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimHardReward) (*sdk.Result, error) {
|
||||||
|
|
||||||
err := k.ClaimHardReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
err := k.ClaimHardReward(ctx, msg.Sender, types.MultiplierName(msg.MultiplierName))
|
||||||
@ -44,3 +58,14 @@ func handleMsgClaimHardReward(ctx sdk.Context, k keeper.Keeper, msg types.MsgCla
|
|||||||
Events: ctx.EventManager().Events(),
|
Events: ctx.EventManager().Events(),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleMsgClaimHardRewardVVesting(ctx sdk.Context, k keeper.Keeper, msg types.MsgClaimHardRewardVVesting) (*sdk.Result, error) {
|
||||||
|
|
||||||
|
err := k.ClaimHardRewardVVesting(ctx, msg.Sender, msg.Receiver, types.MultiplierName(msg.MultiplierName))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &sdk.Result{
|
||||||
|
Events: ctx.EventManager().Events(),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -74,6 +74,66 @@ func (k Keeper) ClaimUSDXMintingReward(ctx sdk.Context, addr sdk.AccAddress, mul
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClaimUSDXMintingReward sends the reward amount to the input receiver address and zero's out the claim in the store
|
||||||
|
func (k Keeper) ClaimUSDXMintingRewardVVesting(ctx sdk.Context, owner, receiver sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||||
|
claim, found := k.GetUSDXMintingClaim(ctx, owner)
|
||||||
|
if !found {
|
||||||
|
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
acc := k.accountKeeper.GetAccount(ctx, owner)
|
||||||
|
if acc == nil {
|
||||||
|
return sdkerrors.Wrapf(types.ErrAccountNotFound, "address not found: %s", owner)
|
||||||
|
}
|
||||||
|
_, ok := acc.(*validatorvesting.ValidatorVestingAccount)
|
||||||
|
if !ok {
|
||||||
|
return sdkerrors.Wrapf(types.ErrInvalidAccountType, "owner account must be validator vesting account %s", owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
multiplier, found := k.GetMultiplier(ctx, multiplierName)
|
||||||
|
if !found {
|
||||||
|
return sdkerrors.Wrapf(types.ErrInvalidMultiplier, string(multiplierName))
|
||||||
|
}
|
||||||
|
|
||||||
|
claimEnd := k.GetClaimEnd(ctx)
|
||||||
|
|
||||||
|
if ctx.BlockTime().After(claimEnd) {
|
||||||
|
return sdkerrors.Wrapf(types.ErrClaimExpired, "block time %s > claim end time %s", ctx.BlockTime(), claimEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
claim, err := k.SynchronizeUSDXMintingClaim(ctx, claim)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
rewardAmount := claim.Reward.Amount.ToDec().Mul(multiplier.Factor).RoundInt()
|
||||||
|
if rewardAmount.IsZero() {
|
||||||
|
return types.ErrZeroClaim
|
||||||
|
}
|
||||||
|
rewardCoin := sdk.NewCoin(claim.Reward.Denom, rewardAmount)
|
||||||
|
length, err := k.GetPeriodLength(ctx, multiplier)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, receiver, sdk.NewCoins(rewardCoin), length)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
k.ZeroUSDXMintingClaim(ctx, claim)
|
||||||
|
|
||||||
|
ctx.EventManager().EmitEvent(
|
||||||
|
sdk.NewEvent(
|
||||||
|
types.EventTypeClaim,
|
||||||
|
sdk.NewAttribute(types.AttributeKeyClaimedBy, claim.GetOwner().String()),
|
||||||
|
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.GetReward().String()),
|
||||||
|
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.GetType()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// ClaimHardReward sends the reward amount to the input address and zero's out the claim in the store
|
// ClaimHardReward sends the reward amount to the input address and zero's out the claim in the store
|
||||||
func (k Keeper) ClaimHardReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName types.MultiplierName) error {
|
func (k Keeper) ClaimHardReward(ctx sdk.Context, addr sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||||
_, found := k.GetHardLiquidityProviderClaim(ctx, addr)
|
_, found := k.GetHardLiquidityProviderClaim(ctx, addr)
|
||||||
@ -133,6 +193,74 @@ func (k Keeper) ClaimHardReward(ctx sdk.Context, addr sdk.AccAddress, multiplier
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ClaimHardReward sends the reward amount to the input address and zero's out the claim in the store
|
||||||
|
func (k Keeper) ClaimHardRewardVVesting(ctx sdk.Context, owner, receiver sdk.AccAddress, multiplierName types.MultiplierName) error {
|
||||||
|
_, found := k.GetHardLiquidityProviderClaim(ctx, owner)
|
||||||
|
if !found {
|
||||||
|
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
acc := k.accountKeeper.GetAccount(ctx, owner)
|
||||||
|
if acc == nil {
|
||||||
|
return sdkerrors.Wrapf(types.ErrAccountNotFound, "address not found: %s", owner)
|
||||||
|
}
|
||||||
|
_, ok := acc.(*validatorvesting.ValidatorVestingAccount)
|
||||||
|
if !ok {
|
||||||
|
return sdkerrors.Wrapf(types.ErrInvalidAccountType, "owner account must be validator vesting account %s", owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
multiplier, found := k.GetMultiplier(ctx, multiplierName)
|
||||||
|
if !found {
|
||||||
|
return sdkerrors.Wrapf(types.ErrInvalidMultiplier, string(multiplierName))
|
||||||
|
}
|
||||||
|
|
||||||
|
claimEnd := k.GetClaimEnd(ctx)
|
||||||
|
|
||||||
|
if ctx.BlockTime().After(claimEnd) {
|
||||||
|
return sdkerrors.Wrapf(types.ErrClaimExpired, "block time %s > claim end time %s", ctx.BlockTime(), claimEnd)
|
||||||
|
}
|
||||||
|
|
||||||
|
k.SynchronizeHardLiquidityProviderClaim(ctx, owner)
|
||||||
|
|
||||||
|
claim, found := k.GetHardLiquidityProviderClaim(ctx, owner)
|
||||||
|
if !found {
|
||||||
|
return sdkerrors.Wrapf(types.ErrClaimNotFound, "address: %s", owner)
|
||||||
|
}
|
||||||
|
|
||||||
|
var rewardCoins sdk.Coins
|
||||||
|
for _, coin := range claim.Reward {
|
||||||
|
rewardAmount := coin.Amount.ToDec().Mul(multiplier.Factor).RoundInt()
|
||||||
|
if rewardAmount.IsZero() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
rewardCoins = append(rewardCoins, sdk.NewCoin(coin.Denom, rewardAmount))
|
||||||
|
}
|
||||||
|
if rewardCoins.IsZero() {
|
||||||
|
return types.ErrZeroClaim
|
||||||
|
}
|
||||||
|
length, err := k.GetPeriodLength(ctx, multiplier)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
err = k.SendTimeLockedCoinsToAccount(ctx, types.IncentiveMacc, receiver, rewardCoins, length)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
k.ZeroHardLiquidityProviderClaim(ctx, claim)
|
||||||
|
|
||||||
|
ctx.EventManager().EmitEvent(
|
||||||
|
sdk.NewEvent(
|
||||||
|
types.EventTypeClaim,
|
||||||
|
sdk.NewAttribute(types.AttributeKeyClaimedBy, claim.GetOwner().String()),
|
||||||
|
sdk.NewAttribute(types.AttributeKeyClaimAmount, claim.GetReward().String()),
|
||||||
|
sdk.NewAttribute(types.AttributeKeyClaimType, claim.GetType()),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// SendTimeLockedCoinsToAccount sends time-locked coins from the input module account to the recipient. If the recipients account is not a vesting account and the input length is greater than zero, the recipient account is converted to a periodic vesting account and the coins are added to the vesting balance as a vesting period with the input length.
|
// SendTimeLockedCoinsToAccount sends time-locked coins from the input module account to the recipient. If the recipients account is not a vesting account and the input length is greater than zero, the recipient account is converted to a periodic vesting account and the coins are added to the vesting balance as a vesting period with the input length.
|
||||||
func (k Keeper) SendTimeLockedCoinsToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, length int64) error {
|
func (k Keeper) SendTimeLockedCoinsToAccount(ctx sdk.Context, senderModule string, recipientAddr sdk.AccAddress, amt sdk.Coins, length int64) error {
|
||||||
macc := k.supplyKeeper.GetModuleAccount(ctx, senderModule)
|
macc := k.supplyKeeper.GetModuleAccount(ctx, senderModule)
|
||||||
|
@ -155,6 +155,156 @@ func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaim() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *KeeperTestSuite) TestPayoutUSDXMintingClaimVVesting() {
|
||||||
|
type args struct {
|
||||||
|
ctype string
|
||||||
|
rewardsPerSecond sdk.Coin
|
||||||
|
initialTime time.Time
|
||||||
|
initialCollateral sdk.Coin
|
||||||
|
initialPrincipal sdk.Coin
|
||||||
|
multipliers types.Multipliers
|
||||||
|
multiplier types.MultiplierName
|
||||||
|
timeElapsed int
|
||||||
|
expectedBalance sdk.Coins
|
||||||
|
expectedPeriods vesting.Periods
|
||||||
|
isPeriodicVestingAccount bool
|
||||||
|
}
|
||||||
|
type errArgs struct {
|
||||||
|
expectPass bool
|
||||||
|
contains string
|
||||||
|
}
|
||||||
|
type test struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
errArgs errArgs
|
||||||
|
}
|
||||||
|
testCases := []test{
|
||||||
|
{
|
||||||
|
"valid 1 day",
|
||||||
|
args{
|
||||||
|
ctype: "bnb-a",
|
||||||
|
rewardsPerSecond: c("ukava", 122354),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
initialCollateral: c("bnb", 1000000000000),
|
||||||
|
initialPrincipal: c("usdx", 10000000000),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 86400,
|
||||||
|
expectedBalance: cs(c("ukava", 11571385600)),
|
||||||
|
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("ukava", 10571385600))}},
|
||||||
|
isPeriodicVestingAccount: true,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: true,
|
||||||
|
contains: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid zero rewards",
|
||||||
|
args{
|
||||||
|
ctype: "bnb-a",
|
||||||
|
rewardsPerSecond: c("ukava", 0),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
initialCollateral: c("bnb", 1000000000000),
|
||||||
|
initialPrincipal: c("usdx", 10000000000),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 86400,
|
||||||
|
expectedBalance: cs(),
|
||||||
|
expectedPeriods: vesting.Periods{},
|
||||||
|
isPeriodicVestingAccount: false,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: false,
|
||||||
|
contains: "claim amount rounds to zero",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
for _, tc := range testCases {
|
||||||
|
suite.Run(tc.name, func() {
|
||||||
|
suite.SetupWithGenState()
|
||||||
|
suite.ctx = suite.ctx.WithBlockTime(tc.args.initialTime)
|
||||||
|
|
||||||
|
// setup incentive state
|
||||||
|
params := types.NewParams(
|
||||||
|
types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
|
||||||
|
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), cs(tc.args.rewardsPerSecond))},
|
||||||
|
types.MultiRewardPeriods{types.NewMultiRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), cs(tc.args.rewardsPerSecond))},
|
||||||
|
types.RewardPeriods{types.NewRewardPeriod(true, tc.args.ctype, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)},
|
||||||
|
tc.args.multipliers,
|
||||||
|
tc.args.initialTime.Add(time.Hour*24*365*5),
|
||||||
|
)
|
||||||
|
suite.keeper.SetParams(suite.ctx, params)
|
||||||
|
suite.keeper.SetPreviousUSDXMintingAccrualTime(suite.ctx, tc.args.ctype, tc.args.initialTime)
|
||||||
|
suite.keeper.SetUSDXMintingRewardFactor(suite.ctx, tc.args.ctype, sdk.ZeroDec())
|
||||||
|
|
||||||
|
// sets addrs[2] to be a validator vesting account
|
||||||
|
ak := suite.app.GetAccountKeeper()
|
||||||
|
acc := ak.GetAccount(suite.ctx, suite.addrs[2])
|
||||||
|
bacc := auth.NewBaseAccount(acc.GetAddress(), acc.GetCoins(), acc.GetPubKey(), acc.GetAccountNumber(), acc.GetSequence())
|
||||||
|
bva, err2 := vesting.NewBaseVestingAccount(bacc, cs(c("ukava", 400)), suite.ctx.BlockTime().Unix()+16)
|
||||||
|
suite.Require().NoError(err2)
|
||||||
|
periods := vesting.Periods{
|
||||||
|
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
||||||
|
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
||||||
|
vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))},
|
||||||
|
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
||||||
|
}
|
||||||
|
vva := validatorvesting.NewValidatorVestingAccountRaw(bva, suite.ctx.BlockTime().Unix(), periods, sdk.ConsAddress{}, nil, 90)
|
||||||
|
ak.SetAccount(suite.ctx, vva)
|
||||||
|
|
||||||
|
// setup account state
|
||||||
|
sk := suite.app.GetSupplyKeeper()
|
||||||
|
err := sk.MintCoins(suite.ctx, cdptypes.ModuleName, sdk.NewCoins(tc.args.initialCollateral))
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
err = sk.SendCoinsFromModuleToAccount(suite.ctx, cdptypes.ModuleName, suite.addrs[2], sdk.NewCoins(tc.args.initialCollateral))
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// setup kavadist state
|
||||||
|
err = sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("ukava", 1000000000000)))
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// setup cdp state
|
||||||
|
cdpKeeper := suite.app.GetCDPKeeper()
|
||||||
|
err = cdpKeeper.AddCdp(suite.ctx, suite.addrs[2], tc.args.initialCollateral, tc.args.initialPrincipal, tc.args.ctype)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
claim, found := suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[2])
|
||||||
|
suite.Require().True(found)
|
||||||
|
suite.Require().Equal(sdk.ZeroDec(), claim.RewardIndexes[0].RewardFactor)
|
||||||
|
|
||||||
|
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * tc.args.timeElapsed))
|
||||||
|
suite.ctx = suite.ctx.WithBlockTime(updatedBlockTime)
|
||||||
|
rewardPeriod, found := suite.keeper.GetUSDXMintingRewardPeriod(suite.ctx, tc.args.ctype)
|
||||||
|
suite.Require().True(found)
|
||||||
|
err = suite.keeper.AccumulateUSDXMintingRewards(suite.ctx, rewardPeriod)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
err = suite.keeper.ClaimUSDXMintingRewardVVesting(suite.ctx, suite.addrs[2], suite.addrs[0], tc.args.multiplier)
|
||||||
|
|
||||||
|
if tc.errArgs.expectPass {
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
ak := suite.app.GetAccountKeeper()
|
||||||
|
acc := ak.GetAccount(suite.ctx, suite.addrs[0])
|
||||||
|
suite.Require().Equal(tc.args.expectedBalance, acc.GetCoins()) // TODO check balance change to decouple from initialized account balance.
|
||||||
|
|
||||||
|
if tc.args.isPeriodicVestingAccount {
|
||||||
|
vacc, ok := acc.(*vesting.PeriodicVestingAccount)
|
||||||
|
suite.Require().True(ok)
|
||||||
|
suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods)
|
||||||
|
}
|
||||||
|
|
||||||
|
claim, found := suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[2])
|
||||||
|
suite.Require().True(found)
|
||||||
|
suite.Require().Equal(c("ukava", 0), claim.Reward)
|
||||||
|
} else {
|
||||||
|
suite.Require().Error(err)
|
||||||
|
suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
|
func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
|
||||||
type args struct {
|
type args struct {
|
||||||
deposit sdk.Coins
|
deposit sdk.Coins
|
||||||
@ -431,6 +581,296 @@ func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaim() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (suite *KeeperTestSuite) TestPayoutHardLiquidityProviderClaimVVesting() {
|
||||||
|
type args struct {
|
||||||
|
deposit sdk.Coins
|
||||||
|
borrow sdk.Coins
|
||||||
|
rewardsPerSecond sdk.Coins
|
||||||
|
initialTime time.Time
|
||||||
|
multipliers types.Multipliers
|
||||||
|
multiplier types.MultiplierName
|
||||||
|
timeElapsed int64
|
||||||
|
expectedRewards sdk.Coins
|
||||||
|
expectedPeriods vesting.Periods
|
||||||
|
isPeriodicVestingAccount bool
|
||||||
|
}
|
||||||
|
type errArgs struct {
|
||||||
|
expectPass bool
|
||||||
|
contains string
|
||||||
|
}
|
||||||
|
type test struct {
|
||||||
|
name string
|
||||||
|
args args
|
||||||
|
errArgs errArgs
|
||||||
|
}
|
||||||
|
testCases := []test{
|
||||||
|
{
|
||||||
|
"single reward denom: valid 1 day",
|
||||||
|
args{
|
||||||
|
deposit: cs(c("bnb", 10000000000)),
|
||||||
|
borrow: cs(c("bnb", 5000000000)),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 86400,
|
||||||
|
expectedRewards: cs(c("hard", 21142771200)), // 10571385600 (deposit reward) + 10571385600 (borrow reward)
|
||||||
|
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("hard", 21142771200))}},
|
||||||
|
isPeriodicVestingAccount: true,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: true,
|
||||||
|
contains: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"single reward denom: valid 10 days",
|
||||||
|
args{
|
||||||
|
deposit: cs(c("bnb", 10000000000)),
|
||||||
|
borrow: cs(c("bnb", 5000000000)),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354)),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 864000,
|
||||||
|
expectedRewards: cs(c("hard", 211427712000)), // 105713856000 (deposit reward) + 105713856000 (borrow reward)
|
||||||
|
expectedPeriods: vesting.Periods{vesting.Period{Length: 32140800, Amount: cs(c("hard", 211427712000))}},
|
||||||
|
isPeriodicVestingAccount: true,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: true,
|
||||||
|
contains: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"invalid zero rewards",
|
||||||
|
args{
|
||||||
|
deposit: cs(c("bnb", 10000000000)),
|
||||||
|
borrow: cs(c("bnb", 5000000000)),
|
||||||
|
rewardsPerSecond: cs(c("hard", 0)),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 86400,
|
||||||
|
expectedRewards: cs(c("hard", 0)),
|
||||||
|
expectedPeriods: vesting.Periods{},
|
||||||
|
isPeriodicVestingAccount: false,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: false,
|
||||||
|
contains: "claim amount rounds to zero",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple reward denoms: valid 1 day",
|
||||||
|
args{
|
||||||
|
deposit: cs(c("bnb", 10000000000)),
|
||||||
|
borrow: cs(c("bnb", 5000000000)),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354), c("ukava", 122354)),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 86400,
|
||||||
|
expectedRewards: cs(c("hard", 21142771200), c("ukava", 21142771200)), // 10571385600 (deposit reward) + 10571385600 (borrow reward)
|
||||||
|
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("hard", 21142771200), c("ukava", 21142771200))}},
|
||||||
|
isPeriodicVestingAccount: true,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: true,
|
||||||
|
contains: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple reward denoms: valid 10 days",
|
||||||
|
args{
|
||||||
|
deposit: cs(c("bnb", 10000000000)),
|
||||||
|
borrow: cs(c("bnb", 5000000000)),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354), c("ukava", 122354)),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 864000,
|
||||||
|
expectedRewards: cs(c("hard", 211427712000), c("ukava", 211427712000)), // 105713856000 (deposit reward) + 105713856000 (borrow reward)
|
||||||
|
expectedPeriods: vesting.Periods{vesting.Period{Length: 32140800, Amount: cs(c("hard", 211427712000), c("ukava", 211427712000))}},
|
||||||
|
isPeriodicVestingAccount: true,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: true,
|
||||||
|
contains: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"multiple reward denoms with different rewards per second: valid 1 day",
|
||||||
|
args{
|
||||||
|
deposit: cs(c("bnb", 10000000000)),
|
||||||
|
borrow: cs(c("bnb", 5000000000)),
|
||||||
|
rewardsPerSecond: cs(c("hard", 122354), c("ukava", 222222)),
|
||||||
|
initialTime: time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC),
|
||||||
|
multipliers: types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
multiplier: types.MultiplierName("large"),
|
||||||
|
timeElapsed: 86400,
|
||||||
|
expectedRewards: cs(c("hard", 21142771200), c("ukava", 38399961600)),
|
||||||
|
expectedPeriods: vesting.Periods{vesting.Period{Length: 32918400, Amount: cs(c("hard", 21142771200), c("ukava", 38399961600))}},
|
||||||
|
isPeriodicVestingAccount: true,
|
||||||
|
},
|
||||||
|
errArgs{
|
||||||
|
expectPass: true,
|
||||||
|
contains: "",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
suite.Run(tc.name, func() {
|
||||||
|
suite.SetupWithGenState()
|
||||||
|
suite.ctx = suite.ctx.WithBlockTime(tc.args.initialTime)
|
||||||
|
|
||||||
|
// setup kavadist state
|
||||||
|
sk := suite.app.GetSupplyKeeper()
|
||||||
|
err := sk.MintCoins(suite.ctx, kavadist.ModuleName, cs(c("hard", 1000000000000000000), c("ukava", 1000000000000000000)))
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// Set up generic reward periods
|
||||||
|
var multiRewardPeriods types.MultiRewardPeriods
|
||||||
|
var rewardPeriods types.RewardPeriods
|
||||||
|
for _, coin := range tc.args.deposit {
|
||||||
|
if len(tc.args.rewardsPerSecond) > 0 {
|
||||||
|
rewardPeriod := types.NewRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond[0])
|
||||||
|
rewardPeriods = append(rewardPeriods, rewardPeriod)
|
||||||
|
}
|
||||||
|
multiRewardPeriod := types.NewMultiRewardPeriod(true, coin.Denom, tc.args.initialTime, tc.args.initialTime.Add(time.Hour*24*365*4), tc.args.rewardsPerSecond)
|
||||||
|
multiRewardPeriods = append(multiRewardPeriods, multiRewardPeriod)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up generic reward periods
|
||||||
|
params := types.NewParams(
|
||||||
|
rewardPeriods, multiRewardPeriods, multiRewardPeriods, rewardPeriods,
|
||||||
|
types.Multipliers{types.NewMultiplier(types.MultiplierName("small"), 1, d("0.25")), types.NewMultiplier(types.MultiplierName("large"), 12, d("1.0"))},
|
||||||
|
tc.args.initialTime.Add(time.Hour*24*365*5),
|
||||||
|
)
|
||||||
|
suite.keeper.SetParams(suite.ctx, params)
|
||||||
|
|
||||||
|
// Set each denom's previous accrual time and supply reward factor
|
||||||
|
if len(tc.args.rewardsPerSecond) > 0 {
|
||||||
|
for _, coin := range tc.args.deposit {
|
||||||
|
suite.keeper.SetPreviousHardSupplyRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
|
||||||
|
var rewardIndexes types.RewardIndexes
|
||||||
|
for _, rewardCoin := range tc.args.rewardsPerSecond {
|
||||||
|
rewardIndex := types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
|
||||||
|
rewardIndexes = append(rewardIndexes, rewardIndex)
|
||||||
|
}
|
||||||
|
suite.keeper.SetHardSupplyRewardIndexes(suite.ctx, coin.Denom, rewardIndexes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set each denom's previous accrual time and borrow reward factor
|
||||||
|
if len(tc.args.rewardsPerSecond) > 0 {
|
||||||
|
for _, coin := range tc.args.borrow {
|
||||||
|
suite.keeper.SetPreviousHardBorrowRewardAccrualTime(suite.ctx, coin.Denom, tc.args.initialTime)
|
||||||
|
var rewardIndexes types.RewardIndexes
|
||||||
|
for _, rewardCoin := range tc.args.rewardsPerSecond {
|
||||||
|
rewardIndex := types.NewRewardIndex(rewardCoin.Denom, sdk.ZeroDec())
|
||||||
|
rewardIndexes = append(rewardIndexes, rewardIndex)
|
||||||
|
}
|
||||||
|
suite.keeper.SetHardBorrowRewardIndexes(suite.ctx, coin.Denom, rewardIndexes)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// sets addrs[3] to be a validator vesting account
|
||||||
|
ak := suite.app.GetAccountKeeper()
|
||||||
|
acc := ak.GetAccount(suite.ctx, suite.addrs[3])
|
||||||
|
bacc := auth.NewBaseAccount(acc.GetAddress(), acc.GetCoins(), acc.GetPubKey(), acc.GetAccountNumber(), acc.GetSequence())
|
||||||
|
bva, err2 := vesting.NewBaseVestingAccount(bacc, cs(c("ukava", 400)), suite.ctx.BlockTime().Unix()+16)
|
||||||
|
suite.Require().NoError(err2)
|
||||||
|
periods := vesting.Periods{
|
||||||
|
vesting.Period{Length: int64(1), Amount: cs(c("ukava", 100))},
|
||||||
|
vesting.Period{Length: int64(2), Amount: cs(c("ukava", 100))},
|
||||||
|
vesting.Period{Length: int64(8), Amount: cs(c("ukava", 100))},
|
||||||
|
vesting.Period{Length: int64(5), Amount: cs(c("ukava", 100))},
|
||||||
|
}
|
||||||
|
vva := validatorvesting.NewValidatorVestingAccountRaw(bva, suite.ctx.BlockTime().Unix(), periods, sdk.ConsAddress{}, nil, 90)
|
||||||
|
ak.SetAccount(suite.ctx, vva)
|
||||||
|
|
||||||
|
hardKeeper := suite.app.GetHardKeeper()
|
||||||
|
userAddr := suite.addrs[3]
|
||||||
|
|
||||||
|
// User deposits and borrows
|
||||||
|
err = hardKeeper.Deposit(suite.ctx, userAddr, tc.args.deposit)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
err = hardKeeper.Borrow(suite.ctx, userAddr, tc.args.borrow)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// Check that Hard hooks initialized a HardLiquidityProviderClaim that has 0 rewards
|
||||||
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(suite.ctx, suite.addrs[3])
|
||||||
|
suite.Require().True(found)
|
||||||
|
for _, coin := range tc.args.deposit {
|
||||||
|
suite.Require().Equal(sdk.ZeroInt(), claim.Reward.AmountOf(coin.Denom))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Set up future runtime context
|
||||||
|
runAtTime := time.Unix(suite.ctx.BlockTime().Unix()+(tc.args.timeElapsed), 0)
|
||||||
|
runCtx := suite.ctx.WithBlockTime(runAtTime)
|
||||||
|
|
||||||
|
// Run Hard begin blocker
|
||||||
|
hard.BeginBlocker(runCtx, suite.hardKeeper)
|
||||||
|
|
||||||
|
// Accumulate supply rewards for each deposit denom
|
||||||
|
for _, coin := range tc.args.deposit {
|
||||||
|
rewardPeriod, found := suite.keeper.GetHardSupplyRewardPeriods(runCtx, coin.Denom)
|
||||||
|
suite.Require().True(found)
|
||||||
|
err = suite.keeper.AccumulateHardSupplyRewards(runCtx, rewardPeriod)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Accumulate borrow rewards for each deposit denom
|
||||||
|
for _, coin := range tc.args.borrow {
|
||||||
|
rewardPeriod, found := suite.keeper.GetHardBorrowRewardPeriods(runCtx, coin.Denom)
|
||||||
|
suite.Require().True(found)
|
||||||
|
err = suite.keeper.AccumulateHardBorrowRewards(runCtx, rewardPeriod)
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sync hard supply rewards
|
||||||
|
deposit, found := suite.hardKeeper.GetDeposit(suite.ctx, suite.addrs[3])
|
||||||
|
suite.Require().True(found)
|
||||||
|
suite.keeper.SynchronizeHardSupplyReward(suite.ctx, deposit)
|
||||||
|
|
||||||
|
// Sync hard borrow rewards
|
||||||
|
borrow, found := suite.hardKeeper.GetBorrow(suite.ctx, suite.addrs[3])
|
||||||
|
suite.Require().True(found)
|
||||||
|
suite.keeper.SynchronizeHardBorrowReward(suite.ctx, borrow)
|
||||||
|
|
||||||
|
// Fetch pre-claim balances
|
||||||
|
preClaimAcc := ak.GetAccount(runCtx, suite.addrs[2])
|
||||||
|
|
||||||
|
err = suite.keeper.ClaimHardRewardVVesting(runCtx, suite.addrs[3], suite.addrs[2], tc.args.multiplier)
|
||||||
|
if tc.errArgs.expectPass {
|
||||||
|
suite.Require().NoError(err)
|
||||||
|
|
||||||
|
// Check that user's balance has increased by expected reward amount
|
||||||
|
postClaimAcc := ak.GetAccount(suite.ctx, suite.addrs[2])
|
||||||
|
suite.Require().Equal(preClaimAcc.GetCoins().Add(tc.args.expectedRewards...), postClaimAcc.GetCoins())
|
||||||
|
|
||||||
|
if tc.args.isPeriodicVestingAccount {
|
||||||
|
vacc, ok := postClaimAcc.(*vesting.PeriodicVestingAccount)
|
||||||
|
suite.Require().True(ok)
|
||||||
|
suite.Require().Equal(tc.args.expectedPeriods, vacc.VestingPeriods)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check that each claim reward coin's amount has been reset to 0
|
||||||
|
claim, found := suite.keeper.GetHardLiquidityProviderClaim(runCtx, suite.addrs[3])
|
||||||
|
suite.Require().True(found)
|
||||||
|
for _, claimRewardCoin := range claim.Reward {
|
||||||
|
suite.Require().Equal(c(claimRewardCoin.Denom, 0), claimRewardCoin)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
suite.Require().Error(err)
|
||||||
|
suite.Require().True(strings.Contains(err.Error(), tc.errArgs.contains))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() {
|
func (suite *KeeperTestSuite) TestSendCoinsToPeriodicVestingAccount() {
|
||||||
type accountArgs struct {
|
type accountArgs struct {
|
||||||
periods vesting.Periods
|
periods vesting.Periods
|
||||||
|
@ -21,4 +21,6 @@ func RegisterCodec(cdc *codec.Codec) {
|
|||||||
// Register msgs
|
// Register msgs
|
||||||
cdc.RegisterConcrete(MsgClaimUSDXMintingReward{}, "incentive/MsgClaimUSDXMintingReward", nil)
|
cdc.RegisterConcrete(MsgClaimUSDXMintingReward{}, "incentive/MsgClaimUSDXMintingReward", nil)
|
||||||
cdc.RegisterConcrete(MsgClaimHardReward{}, "incentive/MsgClaimHardReward", nil)
|
cdc.RegisterConcrete(MsgClaimHardReward{}, "incentive/MsgClaimHardReward", nil)
|
||||||
|
cdc.RegisterConcrete(MsgClaimUSDXMintingRewardVVesting{}, "incentive/MsgClaimUSDXRewardVVesting", nil)
|
||||||
|
cdc.RegisterConcrete(MsgClaimHardRewardVVesting{}, "incentive/MsgClaimHardRewardVVesting", nil)
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,8 @@ import (
|
|||||||
// ensure Msg interface compliance at compile time
|
// ensure Msg interface compliance at compile time
|
||||||
var _ sdk.Msg = &MsgClaimUSDXMintingReward{}
|
var _ sdk.Msg = &MsgClaimUSDXMintingReward{}
|
||||||
var _ sdk.Msg = &MsgClaimHardReward{}
|
var _ sdk.Msg = &MsgClaimHardReward{}
|
||||||
|
var _ sdk.Msg = &MsgClaimHardRewardVVesting{}
|
||||||
|
var _ sdk.Msg = &MsgClaimUSDXMintingRewardVVesting{}
|
||||||
|
|
||||||
// MsgClaimUSDXMintingReward message type used to claim USDX minting rewards
|
// MsgClaimUSDXMintingReward message type used to claim USDX minting rewards
|
||||||
type MsgClaimUSDXMintingReward struct {
|
type MsgClaimUSDXMintingReward struct {
|
||||||
@ -50,6 +52,52 @@ func (msg MsgClaimUSDXMintingReward) GetSigners() []sdk.AccAddress {
|
|||||||
return []sdk.AccAddress{msg.Sender}
|
return []sdk.AccAddress{msg.Sender}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MsgClaimUSDXMintingRewardVVesting message type used to claim USDX minting rewards for validator vesting accounts
|
||||||
|
type MsgClaimUSDXMintingRewardVVesting struct {
|
||||||
|
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||||
|
Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"`
|
||||||
|
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMsgClaimUSDXMintingRewardVVesting returns a new MsgClaimUSDXMintingReward.
|
||||||
|
func NewMsgClaimUSDXMintingRewardVVesting(sender, receiver sdk.AccAddress, multiplierName string) MsgClaimUSDXMintingRewardVVesting {
|
||||||
|
return MsgClaimUSDXMintingRewardVVesting{
|
||||||
|
Sender: sender,
|
||||||
|
Receiver: receiver,
|
||||||
|
MultiplierName: multiplierName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route return the message type used for routing the message.
|
||||||
|
func (msg MsgClaimUSDXMintingRewardVVesting) Route() string { return RouterKey }
|
||||||
|
|
||||||
|
// Type returns a human-readable string for the message, intended for utilization within tags.
|
||||||
|
func (msg MsgClaimUSDXMintingRewardVVesting) Type() string {
|
||||||
|
return "claim_usdx_minting_reward_vvesting"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBasic does a simple validation check that doesn't require access to state.
|
||||||
|
func (msg MsgClaimUSDXMintingRewardVVesting) ValidateBasic() error {
|
||||||
|
if msg.Sender.Empty() {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be empty")
|
||||||
|
}
|
||||||
|
if msg.Receiver.Empty() {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "receiver address cannot be empty")
|
||||||
|
}
|
||||||
|
return MultiplierName(strings.ToLower(msg.MultiplierName)).IsValid()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSignBytes gets the canonical byte representation of the Msg.
|
||||||
|
func (msg MsgClaimUSDXMintingRewardVVesting) GetSignBytes() []byte {
|
||||||
|
bz := ModuleCdc.MustMarshalJSON(msg)
|
||||||
|
return sdk.MustSortJSON(bz)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSigners returns the addresses of signers that must sign.
|
||||||
|
func (msg MsgClaimUSDXMintingRewardVVesting) GetSigners() []sdk.AccAddress {
|
||||||
|
return []sdk.AccAddress{msg.Sender}
|
||||||
|
}
|
||||||
|
|
||||||
// MsgClaimHardReward message type used to claim Hard liquidity provider rewards
|
// MsgClaimHardReward message type used to claim Hard liquidity provider rewards
|
||||||
type MsgClaimHardReward struct {
|
type MsgClaimHardReward struct {
|
||||||
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||||
@ -90,3 +138,49 @@ func (msg MsgClaimHardReward) GetSignBytes() []byte {
|
|||||||
func (msg MsgClaimHardReward) GetSigners() []sdk.AccAddress {
|
func (msg MsgClaimHardReward) GetSigners() []sdk.AccAddress {
|
||||||
return []sdk.AccAddress{msg.Sender}
|
return []sdk.AccAddress{msg.Sender}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MsgClaimHardRewardVVesting message type used to claim Hard liquidity provider rewards for validator vesting accounts
|
||||||
|
type MsgClaimHardRewardVVesting struct {
|
||||||
|
Sender sdk.AccAddress `json:"sender" yaml:"sender"`
|
||||||
|
Receiver sdk.AccAddress `json:"receiver" yaml:"receiver"`
|
||||||
|
MultiplierName string `json:"multiplier_name" yaml:"multiplier_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// NewMsgClaimHardRewardVVesting returns a new MsgClaimHardReward.
|
||||||
|
func NewMsgClaimHardRewardVVesting(sender, receiver sdk.AccAddress, multiplierName string) MsgClaimHardRewardVVesting {
|
||||||
|
return MsgClaimHardRewardVVesting{
|
||||||
|
Sender: sender,
|
||||||
|
Receiver: receiver,
|
||||||
|
MultiplierName: multiplierName,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Route return the message type used for routing the message.
|
||||||
|
func (msg MsgClaimHardRewardVVesting) Route() string { return RouterKey }
|
||||||
|
|
||||||
|
// Type returns a human-readable string for the message, intended for utilization within tags.
|
||||||
|
func (msg MsgClaimHardRewardVVesting) Type() string {
|
||||||
|
return "claim_hard_reward_vvesting"
|
||||||
|
}
|
||||||
|
|
||||||
|
// ValidateBasic does a simple validation check that doesn't require access to state.
|
||||||
|
func (msg MsgClaimHardRewardVVesting) ValidateBasic() error {
|
||||||
|
if msg.Sender.Empty() {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "sender address cannot be empty")
|
||||||
|
}
|
||||||
|
if msg.Receiver.Empty() {
|
||||||
|
return sdkerrors.Wrap(sdkerrors.ErrInvalidAddress, "receiver address cannot be empty")
|
||||||
|
}
|
||||||
|
return MultiplierName(strings.ToLower(msg.MultiplierName)).IsValid()
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSignBytes gets the canonical byte representation of the Msg.
|
||||||
|
func (msg MsgClaimHardRewardVVesting) GetSignBytes() []byte {
|
||||||
|
bz := ModuleCdc.MustMarshalJSON(msg)
|
||||||
|
return sdk.MustSortJSON(bz)
|
||||||
|
}
|
||||||
|
|
||||||
|
// GetSigners returns the addresses of signers that must sign.
|
||||||
|
func (msg MsgClaimHardRewardVVesting) GetSigners() []sdk.AccAddress {
|
||||||
|
return []sdk.AccAddress{msg.Sender}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user