mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-25 07:45:18 +00:00
Swap users accumulate rewards (#950)
* add swap claim type * add store methods for swap claims * add swap claims to genesis state * tidy up cdp and hard hook doc comments * add uncalled hooks to the swap keeper * add swap rewards sync method * add swap rewards init method * connect swap rewards via swap hooks * Update querier and client for swap claims (#951) * refactor querier to dedupe code * add swap claims querier endpoint * add swap claim querying to rest * add swap claim querying to cli * add keeper method to iterate swap reward indexes * simplify reward-factors query endpoint, add swap * update swap hook to match latest swap branch * rename func to not collide with latest swap branch * Squash merge swap-acceptance branch (#956) * add failing acceptance test for a user depositing into a pool * implement GetAccount test helper * implement swap.MsgDeposit for creating and adding liquidity to a pool * update aliases, add event types, and fix typo/compiler errors in handler test * use only aliases names in handler test (don't use swap types -- ensures we have run aliasgen), add assertion for even type message * implement account and module account balance checks in handler test * fill out handler assertions for testing keeper state and events * update signed json representation and register swap/MsgDeposit for proper encoding * fill out boilerplate to get handler test to compile * alias gen for pool * add handling of message type; fill in deposit keeper method for succesful compile; noop but test assertions now run up to module acc not nil check * add module account permissions for swap module -- fixes module account creation; pass account keeper and supply keeper into swap keeper to allow the ability to work with user and module accounts * implement create pool logic for msg deposit; allows creation of a of new pool, checking params to see if it is allowed. Initi shares are set, and senders number of shares are stored * Swap migrations scaffolding (#925) * swap module scaffolding * global swap fee * can't think of a reason for begin blocker; removing for abci.go for now; * test pair types; refactor pair name logic; simplify pairs validation and fix stack overflow error * check comparison * use test package * init swap module genesis * add basic marshall tests * remove reward apy from pairs * fix integration helpers * use max swap fee constant; fix validation of swap fee; add tests to cover param validation and param set setup * use noerror over nil * start genesis tests * test param set validation mirrors param validation * add genesis tests * remove print statement * add subtests for genesis test cases; add extra querier test for unknown route; add keeper params testing * add spec * update swagger * find replace hard -> swap in comments * remove unused method * rename pairs to allowed pools; pool is more commonly used, and allowedPool makes it more clear what swap parameter is for. In addition, we won't conflict with Pool data structure for storing a created pool in the store. * remove generated link * missed spec rename * validate token order for allowed pools * fix swagger * json should be snakecase; change allowedPools to allowed_pools * add legacy types * add swap genesis to v0_15 migration * add legacy types * add swap genesis to v0_15 migration * migration revisions Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> * keeper todos * update keeper tests * type todos * update types tests * tx deposit cli cmd * tx deposit rest * Swap module simulation scaffolding (#924) * sims scaffolding * add noop operation * genesis revisions * add param changes * mvoe persistance methods to main keeper file, consolidate tests * make helper methods private. they are tested via deposit method, and unit testing them would make test suite brittle and refactoring difficult * use more clear coin variables * code 1 is reserved, use code 2 and sequence all errors * remove todo * Implement deadline for swap module module message. This is implemented in handler with a interface to easily apply to it to all messages, and separate msg validation concerns from the keeper * move allowed pools to params -- let pool and pool_test focus on pool domain logic, not parameter & governance concerns * update alias * add unitless implementatin of constant product liquidity pool to isolate and enapsulate liquidity logic. Swap methods interfaces are added, but implementation not yet added * nits and todos * add ErrInvalidPool * add tests for edge cases around pool depletion; add explicit panic for edge case that results in a pool reserve being zero; handle pool reinitialization if it is empty * touch up comments and flush out the rest of assertions * add data structures for keeper state storage separate from pool domain objects, and improve structure for easier querying * rename pool name to pool key for events * add support for a denominated pool that uses sdk.Coins and sdk.Coin arguments, keeping tracking of the units in the base pool. This gives nice separation between pool logic, and coin/denom logic * refactor keeper to use new records for storage, and implement pool deposit using the denominated pool * address previous PR comment - reminder for migration if changing account permissions * msg deposit should validate that denoms are not equal * add godoc comments * golint and some poolName -> poolID cleanup * implement adding liquidity to an existing pool * hardcode pools in sims * touch up comment * withdraw keeper logic * withdraw type updates * add withdraw msg tx handler * initial withdraw test * fix panic * use new denominated pool with existing shares * fix: check args on deposit cmd * add slippage limit check for depositing to an existing pool * send coins just before event emission * check liquidity returned is greater than zero for both coins; ensure returned number of shares are greater than zero * add deadline to msgwithdraw * register msgwithdraw * scaffold msgwithdraw types test * register the correct msg * modify swap functions to also return the amount paid for the pool swap fee. This will be used to calculate slippage and for event tracking * add slippage types * add expected withdrawal coins * calculate slippage against expected coins * update withdraw keeper tests * spelling, improve comments on add liquidity math * typo * typo * grammer * typo / grammer * remove pool_id from withdraw msg * add slippage to tx cmd * TestWithdraw_Partial * nit * add withdraw no pool, no deposit record tests * drop event check on partial withdraw test * fix broken link * fix broken link * resolve merge conflicts * ensure swap fee can not be equal to 1; add full implementation of swap pool methods; these implementation ensure that the pool invariant is always greater or equal to the previous invariant * refactor duplicated code into private swap methods * add runtime assertion to always ensure invariant is greater or equal to the previous invariant sub fee on swaps * improve comments for base pool swap functions * add swap exact input and output methods to denominated pool that wrap the base pool interface for swapping * comment touch ups * more comment touchups * fix msg deposit struct tag (#943) * use better name for swap calculation private methods * nits: golint * fix misspelling in method name * Add HARD token governance committee for Hard module (#941) * add hard gov token committee * revisions: update migration * revisions: update test/data file * initial revisions * add TokenCommittee JSONMarshal test * fix SetPermissions method * remove BaseCommittee Type field * add incentive params to allowed params * Add SWP token governance committee for Swap module (#946) * add swp token commitee to migration * update test, add gen export utility method * final revisions: add TODO * remove slippage from withdraw to use min values for coins; add additional validation test cases * update alias for swap module * add withdraw tests to handler for increased coverage; note: first pass, improvements still yet to be made here * refact withdraw keeper to use min amounts; panic for cases that do not happen in normal situations * lint fixes * use total shares to track if pool should be deleted; add more in depth withdraw comment * add exact args for withdraw cmd * extract record update methods * update depositor share record if it exists -- do not overwrite an existing record; ensures no loss of shares if the same address deposits more than once * Swap queries: deposit, pool, pools (#949) * query deposits types * implement deposit querier keeper methods * query deposits CLI * query deposits REST * query types for pool/pools * pool/pools querier keeper methods * pool/pools CLI * pool/pools REST * basic pool/pools query tests * basic deposit querier test * iterate share records via owner bytes * nit: add example for querying deposits by owner only Co-authored-by: karzak <kjydavis3@gmail.com> * feat: add REST tx handler for swap LP withdrawals Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: Denali Marsh <denali@kava.io> Co-authored-by: denalimarsh <denalimarsh@gmail.com> Co-authored-by: karzak <kjydavis3@gmail.com> * expand incentive cli query docs Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: Denali Marsh <denali@kava.io> Co-authored-by: denalimarsh <denalimarsh@gmail.com> Co-authored-by: karzak <kjydavis3@gmail.com> * minor update to godoc comment Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com> Co-authored-by: Denali Marsh <denali@kava.io> Co-authored-by: denalimarsh <denalimarsh@gmail.com> Co-authored-by: karzak <kjydavis3@gmail.com>
This commit is contained in:
parent
65052ce31a
commit
4beaf0de54
@ -390,7 +390,7 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts AppOptio
|
||||
app.accountKeeper,
|
||||
app.supplyKeeper,
|
||||
)
|
||||
app.swapKeeper = swap.NewKeeper(
|
||||
swapKeeper := swap.NewKeeper(
|
||||
app.cdc,
|
||||
keys[swap.StoreKey],
|
||||
swapSubspace,
|
||||
@ -406,11 +406,11 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts AppOptio
|
||||
&hardKeeper,
|
||||
app.accountKeeper,
|
||||
&stakingKeeper,
|
||||
app.swapKeeper,
|
||||
&swapKeeper,
|
||||
)
|
||||
|
||||
// register the staking hooks
|
||||
// NOTE: stakingKeeper above is passed by reference, so that it will contain these hooks
|
||||
// NOTE: These keepers are passed by reference above, so they will contain these hooks.
|
||||
app.stakingKeeper = *stakingKeeper.SetHooks(
|
||||
staking.NewMultiStakingHooks(app.distrKeeper.Hooks(), app.slashingKeeper.Hooks(), app.incentiveKeeper.Hooks()))
|
||||
|
||||
@ -418,6 +418,8 @@ func NewApp(logger log.Logger, db dbm.DB, traceStore io.Writer, appOpts AppOptio
|
||||
|
||||
app.hardKeeper = *hardKeeper.SetHooks(hard.NewMultiHARDHooks(app.incentiveKeeper.Hooks()))
|
||||
|
||||
app.swapKeeper = *swapKeeper.SetHooks(app.incentiveKeeper.Hooks())
|
||||
|
||||
// create the module manager (Note: Any module instantiated in the module manager that is later modified
|
||||
// must be passed by reference here.)
|
||||
app.mm = module.NewManager(
|
||||
|
@ -448,9 +448,10 @@ func Incentive(incentiveGS v0_14incentive.GenesisState) v0_15incentive.GenesisSt
|
||||
hardSupplyAccumulationTimes,
|
||||
hardBorrowAccumulationTimes,
|
||||
hardDelegatorAccumulationTimes,
|
||||
v0_15incentive.DefaultGenesisAccumulationTimes, // There is no previous swap rewards to accumulation starts at genesis time.
|
||||
v0_15incentive.DefaultGenesisAccumulationTimes, // There is no previous swap rewards so accumulation starts at genesis time.
|
||||
usdxMintingClaims,
|
||||
hardClaims,
|
||||
delegatorClaims,
|
||||
v0_15incentive.DefaultSwapClaims,
|
||||
)
|
||||
}
|
||||
|
@ -45,10 +45,10 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, paramstore subspace.Subspace,
|
||||
}
|
||||
}
|
||||
|
||||
// SetHooks sets the cdp keeper hooks
|
||||
// SetHooks adds hooks to the keeper.
|
||||
func (k *Keeper) SetHooks(hooks types.CDPHooks) *Keeper {
|
||||
if k.hooks != nil {
|
||||
panic("cannot set validator hooks twice")
|
||||
panic("cannot set cdp hooks twice")
|
||||
}
|
||||
k.hooks = hooks
|
||||
return k
|
||||
|
@ -45,10 +45,10 @@ func NewKeeper(cdc *codec.Codec, key sdk.StoreKey, paramstore subspace.Subspace,
|
||||
}
|
||||
}
|
||||
|
||||
// SetHooks sets the cdp keeper hooks
|
||||
// SetHooks adds hooks to the keeper.
|
||||
func (k *Keeper) SetHooks(hooks types.HARDHooks) *Keeper {
|
||||
if k.hooks != nil {
|
||||
panic("cannot set validator hooks twice")
|
||||
panic("cannot set hard hooks twice")
|
||||
}
|
||||
k.hooks = hooks
|
||||
return k
|
||||
|
@ -1,8 +1,5 @@
|
||||
// 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
|
||||
// Code generated by aliasgen tool (github.com/rhuairahrighairidh/aliasgen) DO NOT EDIT.
|
||||
|
||||
package incentive
|
||||
|
||||
import (
|
||||
@ -11,166 +8,175 @@ import (
|
||||
)
|
||||
|
||||
const (
|
||||
USDXMintingClaimType = types.USDXMintingClaimType
|
||||
HardLiquidityProviderClaimType = types.HardLiquidityProviderClaimType
|
||||
BondDenom = types.BondDenom
|
||||
EventTypeClaim = types.EventTypeClaim
|
||||
EventTypeRewardPeriod = types.EventTypeRewardPeriod
|
||||
EventTypeClaimPeriod = types.EventTypeClaimPeriod
|
||||
EventTypeClaimPeriodExpiry = types.EventTypeClaimPeriodExpiry
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
AttributeKeyClaimedBy = types.AttributeKeyClaimedBy
|
||||
AttributeKeyClaimAmount = types.AttributeKeyClaimAmount
|
||||
AttributeKeyClaimType = types.AttributeKeyClaimType
|
||||
AttributeKeyRewardPeriod = types.AttributeKeyRewardPeriod
|
||||
AttributeKeyClaimPeriod = types.AttributeKeyClaimPeriod
|
||||
ModuleName = types.ModuleName
|
||||
StoreKey = types.StoreKey
|
||||
RouterKey = types.RouterKey
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
QuerierRoute = types.QuerierRoute
|
||||
Small = types.Small
|
||||
Medium = types.Medium
|
||||
Large = types.Large
|
||||
QueryGetRewards = types.QueryGetRewards
|
||||
QueryGetHardRewards = types.QueryGetHardRewards
|
||||
QueryGetHardRewardsUnsynced = types.QueryGetHardRewardsUnsynced
|
||||
QueryGetUSDXMintingRewards = types.QueryGetUSDXMintingRewards
|
||||
QueryGetUSDXMintingRewardsUnsynced = types.QueryGetUSDXMintingRewardsUnsynced
|
||||
QueryGetRewardFactors = types.QueryGetRewardFactors
|
||||
QueryGetParams = types.QueryGetParams
|
||||
QueryGetRewardPeriods = types.QueryGetRewardPeriods
|
||||
QueryGetClaimPeriods = types.QueryGetClaimPeriods
|
||||
RestClaimCollateralType = types.RestClaimCollateralType
|
||||
RestClaimOwner = types.RestClaimOwner
|
||||
RestClaimType = types.RestClaimType
|
||||
RestUnsynced = types.RestUnsynced
|
||||
BeginningOfMonth = keeper.BeginningOfMonth
|
||||
MidMonth = keeper.MidMonth
|
||||
PaymentHour = keeper.PaymentHour
|
||||
BeginningOfMonth = keeper.BeginningOfMonth
|
||||
MidMonth = keeper.MidMonth
|
||||
PaymentHour = keeper.PaymentHour
|
||||
AttributeKeyClaimAmount = types.AttributeKeyClaimAmount
|
||||
AttributeKeyClaimPeriod = types.AttributeKeyClaimPeriod
|
||||
AttributeKeyClaimType = types.AttributeKeyClaimType
|
||||
AttributeKeyClaimedBy = types.AttributeKeyClaimedBy
|
||||
AttributeKeyRewardPeriod = types.AttributeKeyRewardPeriod
|
||||
AttributeValueCategory = types.AttributeValueCategory
|
||||
BondDenom = types.BondDenom
|
||||
DefaultParamspace = types.DefaultParamspace
|
||||
DelegatorClaimType = types.DelegatorClaimType
|
||||
EventTypeClaim = types.EventTypeClaim
|
||||
EventTypeClaimPeriod = types.EventTypeClaimPeriod
|
||||
EventTypeClaimPeriodExpiry = types.EventTypeClaimPeriodExpiry
|
||||
EventTypeRewardPeriod = types.EventTypeRewardPeriod
|
||||
HardLiquidityProviderClaimType = types.HardLiquidityProviderClaimType
|
||||
Large = types.Large
|
||||
Medium = types.Medium
|
||||
ModuleName = types.ModuleName
|
||||
QuerierRoute = types.QuerierRoute
|
||||
QueryGetDelegatorRewards = types.QueryGetDelegatorRewards
|
||||
QueryGetHardRewards = types.QueryGetHardRewards
|
||||
QueryGetParams = types.QueryGetParams
|
||||
QueryGetRewardFactors = types.QueryGetRewardFactors
|
||||
QueryGetSwapRewards = types.QueryGetSwapRewards
|
||||
QueryGetUSDXMintingRewards = types.QueryGetUSDXMintingRewards
|
||||
RestClaimCollateralType = types.RestClaimCollateralType
|
||||
RestClaimOwner = types.RestClaimOwner
|
||||
RestClaimType = types.RestClaimType
|
||||
RestUnsynced = types.RestUnsynced
|
||||
RouterKey = types.RouterKey
|
||||
Small = types.Small
|
||||
StoreKey = types.StoreKey
|
||||
SwapClaimType = types.SwapClaimType
|
||||
USDXMintingClaimType = types.USDXMintingClaimType
|
||||
)
|
||||
|
||||
var (
|
||||
// functions aliases
|
||||
GetTotalVestingPeriodLength = types.GetTotalVestingPeriodLength
|
||||
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
||||
NewHardLiquidityProviderClaim = types.NewHardLiquidityProviderClaim
|
||||
NewMultiRewardPeriod = types.NewMultiRewardPeriod
|
||||
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
|
||||
DefaultParams = types.DefaultParams
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
NewRewardPeriod = types.NewRewardPeriod
|
||||
NewMultiplier = types.NewMultiplier
|
||||
NewPeriod = types.NewPeriod
|
||||
NewQueryRewardsParams = types.NewQueryRewardsParams
|
||||
NewQueryUSDXMintingRewardsParams = types.NewQueryUSDXMintingRewardsParams
|
||||
NewQueryUSDXMintingRewardsUnsyncedParams = types.NewQueryUSDXMintingRewardsUnsyncedParams
|
||||
NewQueryHardRewardsParams = types.NewQueryHardRewardsParams
|
||||
NewQueryHardRewardsUnsyncedParams = types.NewQueryHardRewardsUnsyncedParams
|
||||
NewQueryRewardFactorsParams = types.NewQueryRewardFactorsParams
|
||||
NewRewardFactor = types.NewRewardFactor
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
||||
// function aliases
|
||||
CalculateTimeElapsed = keeper.CalculateTimeElapsed
|
||||
NewKeeper = keeper.NewKeeper
|
||||
NewQuerier = keeper.NewQuerier
|
||||
DefaultGenesisState = types.DefaultGenesisState
|
||||
DefaultParams = types.DefaultParams
|
||||
GetTotalVestingPeriodLength = types.GetTotalVestingPeriodLength
|
||||
NewAccumulator = types.NewAccumulator
|
||||
NewDelegatorClaim = types.NewDelegatorClaim
|
||||
NewGenesisAccumulationTime = types.NewGenesisAccumulationTime
|
||||
NewGenesisState = types.NewGenesisState
|
||||
NewHardLiquidityProviderClaim = types.NewHardLiquidityProviderClaim
|
||||
NewMsgClaimDelegatorReward = types.NewMsgClaimDelegatorReward
|
||||
NewMsgClaimDelegatorRewardVVesting = types.NewMsgClaimDelegatorRewardVVesting
|
||||
NewMsgClaimHardReward = types.NewMsgClaimHardReward
|
||||
NewMsgClaimHardRewardVVesting = types.NewMsgClaimHardRewardVVesting
|
||||
NewMsgClaimUSDXMintingReward = types.NewMsgClaimUSDXMintingReward
|
||||
NewMsgClaimUSDXMintingRewardVVesting = types.NewMsgClaimUSDXMintingRewardVVesting
|
||||
NewMultiRewardIndex = types.NewMultiRewardIndex
|
||||
NewMultiRewardPeriod = types.NewMultiRewardPeriod
|
||||
NewMultiplier = types.NewMultiplier
|
||||
NewParams = types.NewParams
|
||||
NewPeriod = types.NewPeriod
|
||||
NewQueryGetRewardFactorsResponse = types.NewQueryGetRewardFactorsResponse
|
||||
NewQueryRewardsParams = types.NewQueryRewardsParams
|
||||
NewRewardIndex = types.NewRewardIndex
|
||||
NewRewardPeriod = types.NewRewardPeriod
|
||||
NewSwapClaim = types.NewSwapClaim
|
||||
NewUSDXMintingClaim = types.NewUSDXMintingClaim
|
||||
ParamKeyTable = types.ParamKeyTable
|
||||
RegisterCodec = types.RegisterCodec
|
||||
|
||||
// variable aliases
|
||||
ModuleCdc = types.ModuleCdc
|
||||
ErrClaimNotFound = types.ErrClaimNotFound
|
||||
ErrRewardPeriodNotFound = types.ErrRewardPeriodNotFound
|
||||
ErrInvalidAccountType = types.ErrInvalidAccountType
|
||||
ErrNoClaimsFound = types.ErrNoClaimsFound
|
||||
ErrInsufficientModAccountBalance = types.ErrInsufficientModAccountBalance
|
||||
ErrAccountNotFound = types.ErrAccountNotFound
|
||||
ErrInvalidMultiplier = types.ErrInvalidMultiplier
|
||||
ErrZeroClaim = types.ErrZeroClaim
|
||||
ErrClaimExpired = types.ErrClaimExpired
|
||||
ErrInvalidClaimType = types.ErrInvalidClaimType
|
||||
ErrInvalidClaimOwner = types.ErrInvalidClaimOwner
|
||||
USDXMintingClaimKeyPrefix = types.USDXMintingClaimKeyPrefix
|
||||
USDXMintingRewardFactorKeyPrefix = types.USDXMintingRewardFactorKeyPrefix
|
||||
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = types.PreviousUSDXMintingRewardAccrualTimeKeyPrefix
|
||||
HardLiquidityClaimKeyPrefix = types.HardLiquidityClaimKeyPrefix
|
||||
HardSupplyRewardIndexesKeyPrefix = types.HardSupplyRewardIndexesKeyPrefix
|
||||
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
||||
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
||||
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
||||
DelegatorRewardIndexesKeyPrefix = types.DelegatorRewardIndexesKeyPrefix
|
||||
PreviousDelegatorRewardAccrualTimeKeyPrefix = types.PreviousDelegatorRewardAccrualTimeKeyPrefix
|
||||
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
||||
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
||||
KeyUSDXMintingRewardPeriods = types.KeyUSDXMintingRewardPeriods
|
||||
KeyHardSupplyRewardPeriods = types.KeyHardSupplyRewardPeriods
|
||||
KeyHardBorrowRewardPeriods = types.KeyHardBorrowRewardPeriods
|
||||
KeyDelegatorRewardPeriods = types.KeyDelegatorRewardPeriods
|
||||
KeyClaimEnd = types.KeyClaimEnd
|
||||
KeyMultipliers = types.KeyMultipliers
|
||||
DefaultActive = types.DefaultActive
|
||||
DefaultRewardPeriods = types.DefaultRewardPeriods
|
||||
DefaultClaimEnd = types.DefaultClaimEnd
|
||||
DefaultDelegatorClaims = types.DefaultDelegatorClaims
|
||||
DefaultGenesisAccumulationTimes = types.DefaultGenesisAccumulationTimes
|
||||
DefaultHardClaims = types.DefaultHardClaims
|
||||
DefaultMultiRewardPeriods = types.DefaultMultiRewardPeriods
|
||||
DefaultMultipliers = types.DefaultMultipliers
|
||||
DefaultDelegatorClaims = types.DefaultDelegatorClaims
|
||||
DefaultRewardPeriods = types.DefaultRewardPeriods
|
||||
DefaultSwapClaims = types.DefaultSwapClaims
|
||||
DefaultUSDXClaims = types.DefaultUSDXClaims
|
||||
DefaultHardClaims = types.DefaultHardClaims
|
||||
DefaultGenesisAccumulationTimes = types.DefaultGenesisAccumulationTimes
|
||||
DefaultClaimEnd = types.DefaultClaimEnd
|
||||
DelegatorClaimKeyPrefix = types.DelegatorClaimKeyPrefix
|
||||
DelegatorRewardIndexesKeyPrefix = types.DelegatorRewardIndexesKeyPrefix
|
||||
ErrAccountNotFound = types.ErrAccountNotFound
|
||||
ErrClaimExpired = types.ErrClaimExpired
|
||||
ErrClaimNotFound = types.ErrClaimNotFound
|
||||
ErrDecreasingRewardFactor = types.ErrDecreasingRewardFactor
|
||||
ErrInsufficientModAccountBalance = types.ErrInsufficientModAccountBalance
|
||||
ErrInvalidAccountType = types.ErrInvalidAccountType
|
||||
ErrInvalidClaimOwner = types.ErrInvalidClaimOwner
|
||||
ErrInvalidClaimType = types.ErrInvalidClaimType
|
||||
ErrInvalidMultiplier = types.ErrInvalidMultiplier
|
||||
ErrNoClaimsFound = types.ErrNoClaimsFound
|
||||
ErrRewardPeriodNotFound = types.ErrRewardPeriodNotFound
|
||||
ErrZeroClaim = types.ErrZeroClaim
|
||||
GovDenom = types.GovDenom
|
||||
PrincipalDenom = types.PrincipalDenom
|
||||
HardBorrowRewardIndexesKeyPrefix = types.HardBorrowRewardIndexesKeyPrefix
|
||||
HardLiquidityClaimKeyPrefix = types.HardLiquidityClaimKeyPrefix
|
||||
HardLiquidityRewardDenom = types.HardLiquidityRewardDenom
|
||||
HardSupplyRewardIndexesKeyPrefix = types.HardSupplyRewardIndexesKeyPrefix
|
||||
IncentiveMacc = types.IncentiveMacc
|
||||
KeyClaimEnd = types.KeyClaimEnd
|
||||
KeyDelegatorRewardPeriods = types.KeyDelegatorRewardPeriods
|
||||
KeyHardBorrowRewardPeriods = types.KeyHardBorrowRewardPeriods
|
||||
KeyHardSupplyRewardPeriods = types.KeyHardSupplyRewardPeriods
|
||||
KeyMultipliers = types.KeyMultipliers
|
||||
KeySwapRewardPeriods = types.KeySwapRewardPeriods
|
||||
KeyUSDXMintingRewardPeriods = types.KeyUSDXMintingRewardPeriods
|
||||
ModuleCdc = types.ModuleCdc
|
||||
PreviousDelegatorRewardAccrualTimeKeyPrefix = types.PreviousDelegatorRewardAccrualTimeKeyPrefix
|
||||
PreviousHardBorrowRewardAccrualTimeKeyPrefix = types.PreviousHardBorrowRewardAccrualTimeKeyPrefix
|
||||
PreviousHardSupplyRewardAccrualTimeKeyPrefix = types.PreviousHardSupplyRewardAccrualTimeKeyPrefix
|
||||
PreviousSwapRewardAccrualTimeKeyPrefix = types.PreviousSwapRewardAccrualTimeKeyPrefix
|
||||
PreviousUSDXMintingRewardAccrualTimeKeyPrefix = types.PreviousUSDXMintingRewardAccrualTimeKeyPrefix
|
||||
PrincipalDenom = types.PrincipalDenom
|
||||
SwapClaimKeyPrefix = types.SwapClaimKeyPrefix
|
||||
SwapRewardIndexesKeyPrefix = types.SwapRewardIndexesKeyPrefix
|
||||
USDXMintingClaimKeyPrefix = types.USDXMintingClaimKeyPrefix
|
||||
USDXMintingRewardDenom = types.USDXMintingRewardDenom
|
||||
USDXMintingRewardFactorKeyPrefix = types.USDXMintingRewardFactorKeyPrefix
|
||||
)
|
||||
|
||||
type (
|
||||
Claim = types.Claim
|
||||
Claims = types.Claims
|
||||
BaseClaim = types.BaseClaim
|
||||
BaseMultiClaim = types.BaseMultiClaim
|
||||
USDXMintingClaim = types.USDXMintingClaim
|
||||
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
|
||||
Hooks = keeper.Hooks
|
||||
Keeper = keeper.Keeper
|
||||
AccountKeeper = types.AccountKeeper
|
||||
Accumulator = types.Accumulator
|
||||
BaseClaim = types.BaseClaim
|
||||
BaseMultiClaim = types.BaseMultiClaim
|
||||
CDPHooks = types.CDPHooks
|
||||
CdpKeeper = types.CdpKeeper
|
||||
Claim = types.Claim
|
||||
Claims = types.Claims
|
||||
DelegatorClaim = types.DelegatorClaim
|
||||
DelegatorClaims = types.DelegatorClaims
|
||||
GenesisAccumulationTime = types.GenesisAccumulationTime
|
||||
GenesisAccumulationTimes = types.GenesisAccumulationTimes
|
||||
GenesisState = types.GenesisState
|
||||
HARDHooks = types.HARDHooks
|
||||
HardKeeper = types.HardKeeper
|
||||
HardLiquidityProviderClaim = types.HardLiquidityProviderClaim
|
||||
HardLiquidityProviderClaims = types.HardLiquidityProviderClaims
|
||||
MsgClaimDelegatorReward = types.MsgClaimDelegatorReward
|
||||
MsgClaimDelegatorRewardVVesting = types.MsgClaimDelegatorRewardVVesting
|
||||
MsgClaimHardReward = types.MsgClaimHardReward
|
||||
MsgClaimHardRewardVVesting = types.MsgClaimHardRewardVVesting
|
||||
MsgClaimUSDXMintingReward = types.MsgClaimUSDXMintingReward
|
||||
MsgClaimUSDXMintingRewardVVesting = types.MsgClaimUSDXMintingRewardVVesting
|
||||
MultiRewardIndex = types.MultiRewardIndex
|
||||
MultiRewardIndexes = types.MultiRewardIndexes
|
||||
MultiRewardPeriod = types.MultiRewardPeriod
|
||||
MultiRewardPeriods = types.MultiRewardPeriods
|
||||
Multiplier = types.Multiplier
|
||||
MultiplierName = types.MultiplierName
|
||||
Multipliers = types.Multipliers
|
||||
ParamSubspace = types.ParamSubspace
|
||||
Params = types.Params
|
||||
QueryGetRewardFactorsResponse = types.QueryGetRewardFactorsResponse
|
||||
QueryRewardsParams = types.QueryRewardsParams
|
||||
RewardIndex = types.RewardIndex
|
||||
RewardIndexes = types.RewardIndexes
|
||||
RewardPeriod = types.RewardPeriod
|
||||
RewardPeriods = types.RewardPeriods
|
||||
StakingKeeper = types.StakingKeeper
|
||||
SupplyKeeper = types.SupplyKeeper
|
||||
SwapClaim = types.SwapClaim
|
||||
SwapClaims = types.SwapClaims
|
||||
SwapKeeper = types.SwapKeeper
|
||||
USDXMintingClaim = types.USDXMintingClaim
|
||||
USDXMintingClaims = types.USDXMintingClaims
|
||||
)
|
||||
|
@ -21,8 +21,15 @@ const (
|
||||
flagType = "type"
|
||||
flagUnsynced = "unsynced"
|
||||
flagDenom = "denom"
|
||||
|
||||
typeDelegator = "delegator"
|
||||
typeHard = "hard"
|
||||
typeUSDXMinting = "usdx-minting"
|
||||
typeSwap = "swap"
|
||||
)
|
||||
|
||||
var rewardTypes = []string{typeDelegator, typeHard, typeUSDXMinting, typeSwap}
|
||||
|
||||
// GetQueryCmd returns the cli query commands for the incentive module
|
||||
func GetQueryCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
incentiveQueryCmd := &cobra.Command{
|
||||
@ -52,13 +59,14 @@ func queryRewardsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
$ %s query %s rewards --type hard
|
||||
$ %s query %s rewards --type usdx-minting
|
||||
$ %s query %s rewards --type delegator
|
||||
$ %s query %s rewards --type swap
|
||||
$ %s query %s rewards --type hard --owner kava15qdefkmwswysgg4qxgqpqr35k3m49pkx2jdfnw
|
||||
$ %s query %s rewards --type hard --unsynced true
|
||||
$ %s query %s rewards --type hard --unsynced
|
||||
`,
|
||||
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName,
|
||||
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName,
|
||||
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName,
|
||||
version.ClientName, types.ModuleName)),
|
||||
version.ClientName, types.ModuleName, version.ClientName, types.ModuleName)),
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
@ -76,90 +84,52 @@ func queryRewardsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
}
|
||||
|
||||
switch strings.ToLower(strType) {
|
||||
case "hard":
|
||||
var claims types.HardLiquidityProviderClaims
|
||||
if boolUnsynced {
|
||||
params := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
|
||||
claims, err = executeHardRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
params := types.NewQueryHardRewardsParams(page, limit, owner)
|
||||
claims, err = executeHardRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case typeHard:
|
||||
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
|
||||
claims, err := executeHardRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cliCtx.PrintOutput(claims)
|
||||
case "usdx-minting":
|
||||
var claims types.USDXMintingClaims
|
||||
if boolUnsynced {
|
||||
params := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
|
||||
claims, err = executeUSDXMintingRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
params := types.NewQueryUSDXMintingRewardsParams(page, limit, owner)
|
||||
claims, err = executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case typeUSDXMinting:
|
||||
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
|
||||
claims, err := executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cliCtx.PrintOutput(claims)
|
||||
case "delegator":
|
||||
var claims types.DelegatorClaims
|
||||
if boolUnsynced {
|
||||
params := types.NewQueryDelegatorRewardsUnsyncedParams(page, limit, owner)
|
||||
claims, err = executeDelegatorRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
params := types.NewQueryDelegatorRewardsParams(page, limit, owner)
|
||||
claims, err = executeDelegatorRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
case typeDelegator:
|
||||
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
|
||||
claims, err := executeDelegatorRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cliCtx.PrintOutput(claims)
|
||||
case typeSwap:
|
||||
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
|
||||
claims, err := executeSwapRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return cliCtx.PrintOutput(claims)
|
||||
default:
|
||||
var hardClaims types.HardLiquidityProviderClaims
|
||||
var usdxMintingClaims types.USDXMintingClaims
|
||||
var delegatorClaims types.DelegatorClaims
|
||||
if boolUnsynced {
|
||||
paramsHard := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
|
||||
hardClaims, err = executeHardRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, paramsHard)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
paramsUSDXMinting := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
|
||||
usdxMintingClaims, err = executeUSDXMintingRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, paramsUSDXMinting)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
paramsDelegator := types.NewQueryDelegatorRewardsUnsyncedParams(page, limit, owner)
|
||||
delegatorClaims, err = executeDelegatorRewardsUnsyncedQuery(queryRoute, cdc, cliCtx, paramsDelegator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
paramsHard := types.NewQueryHardRewardsParams(page, limit, owner)
|
||||
hardClaims, err = executeHardRewardsQuery(queryRoute, cdc, cliCtx, paramsHard)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
paramsUSDXMinting := types.NewQueryUSDXMintingRewardsParams(page, limit, owner)
|
||||
usdxMintingClaims, err = executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, paramsUSDXMinting)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
paramsDelegator := types.NewQueryDelegatorRewardsParams(page, limit, owner)
|
||||
delegatorClaims, err = executeDelegatorRewardsQuery(queryRoute, cdc, cliCtx, paramsDelegator)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
params := types.NewQueryRewardsParams(page, limit, owner, boolUnsynced)
|
||||
|
||||
hardClaims, err := executeHardRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
usdxMintingClaims, err := executeUSDXMintingRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
delegatorClaims, err := executeDelegatorRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
swapClaims, err := executeSwapRewardsQuery(queryRoute, cdc, cliCtx, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if len(hardClaims) > 0 {
|
||||
cliCtx.PrintOutput(hardClaims)
|
||||
@ -170,13 +140,16 @@ func queryRewardsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
if len(delegatorClaims) > 0 {
|
||||
cliCtx.PrintOutput(delegatorClaims)
|
||||
}
|
||||
if len(swapClaims) > 0 {
|
||||
cliCtx.PrintOutput(swapClaims)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagOwner, "", "(optional) filter by owner address")
|
||||
cmd.Flags().String(flagType, "", "(optional) filter by reward type")
|
||||
cmd.Flags().String(flagUnsynced, "", "(optional) get unsynced claims")
|
||||
cmd.Flags().String(flagType, "", fmt.Sprintf("(optional) filter by a reward type: %s", strings.Join(rewardTypes, "|")))
|
||||
cmd.Flags().Bool(flagUnsynced, false, "(optional) get unsynced claims")
|
||||
cmd.Flags().Int(flags.FlagPage, 1, "pagination page rewards of to to query for")
|
||||
cmd.Flags().Int(flags.FlagLimit, 100, "pagination limit of rewards to query for")
|
||||
return cmd
|
||||
@ -213,47 +186,32 @@ func queryRewardFactorsCmd(queryRoute string, cdc *codec.Codec) *cobra.Command {
|
||||
cmd := &cobra.Command{
|
||||
Use: "reward-factors",
|
||||
Short: "get current global reward factors",
|
||||
Long: strings.TrimSpace(`get current global reward factors:
|
||||
|
||||
Example:
|
||||
$ kvcli q hard reward-factors
|
||||
$ kvcli q hard reward-factors --denom bnb`,
|
||||
),
|
||||
Args: cobra.NoArgs,
|
||||
Long: `Get current global reward factors for all reward types.`,
|
||||
Args: cobra.NoArgs,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
cliCtx := context.NewCLIContext().WithCodec(cdc)
|
||||
|
||||
denom := viper.GetString(flagDenom)
|
||||
|
||||
// Construct query with params
|
||||
params := types.NewQueryRewardFactorsParams(denom)
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Execute query
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetRewardFactors)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
res, height, err := cliCtx.QueryWithData(route, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
// Decode and print results
|
||||
var rewardFactors types.RewardFactors
|
||||
if err := cdc.UnmarshalJSON(res, &rewardFactors); err != nil {
|
||||
var response types.QueryGetRewardFactorsResponse
|
||||
if err := cdc.UnmarshalJSON(res, &response); err != nil {
|
||||
return fmt.Errorf("failed to unmarshal reward factors: %w", err)
|
||||
}
|
||||
return cliCtx.PrintOutput(rewardFactors)
|
||||
return cliCtx.PrintOutput(response)
|
||||
},
|
||||
}
|
||||
cmd.Flags().String(flagDenom, "", "(optional) filter reward factors by denom")
|
||||
return cmd
|
||||
}
|
||||
|
||||
func executeHardRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
|
||||
params types.QueryHardRewardsParams) (types.HardLiquidityProviderClaims, error) {
|
||||
func executeHardRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext, params types.QueryRewardsParams) (types.HardLiquidityProviderClaims, error) {
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return types.HardLiquidityProviderClaims{}, err
|
||||
@ -275,31 +233,7 @@ func executeHardRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func executeHardRewardsUnsyncedQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
|
||||
params types.QueryHardRewardsUnsyncedParams) (types.HardLiquidityProviderClaims, error) {
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return types.HardLiquidityProviderClaims{}, err
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetHardRewardsUnsynced)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
return types.HardLiquidityProviderClaims{}, err
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
var claims types.HardLiquidityProviderClaims
|
||||
if err := cdc.UnmarshalJSON(res, &claims); err != nil {
|
||||
return types.HardLiquidityProviderClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
|
||||
}
|
||||
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func executeUSDXMintingRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
|
||||
params types.QueryUSDXMintingRewardsParams) (types.USDXMintingClaims, error) {
|
||||
func executeUSDXMintingRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext, params types.QueryRewardsParams) (types.USDXMintingClaims, error) {
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return types.USDXMintingClaims{}, err
|
||||
@ -321,31 +255,7 @@ func executeUSDXMintingRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func executeUSDXMintingRewardsUnsyncedQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
|
||||
params types.QueryUSDXMintingRewardsUnsyncedParams) (types.USDXMintingClaims, error) {
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return types.USDXMintingClaims{}, err
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetUSDXMintingRewardsUnsynced)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
return types.USDXMintingClaims{}, err
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
var claims types.USDXMintingClaims
|
||||
if err := cdc.UnmarshalJSON(res, &claims); err != nil {
|
||||
return types.USDXMintingClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
|
||||
}
|
||||
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func executeDelegatorRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
|
||||
params types.QueryDelegatorRewardsParams) (types.DelegatorClaims, error) {
|
||||
func executeDelegatorRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext, params types.QueryRewardsParams) (types.DelegatorClaims, error) {
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return types.DelegatorClaims{}, err
|
||||
@ -367,24 +277,23 @@ func executeDelegatorRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx co
|
||||
return claims, nil
|
||||
}
|
||||
|
||||
func executeDelegatorRewardsUnsyncedQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext,
|
||||
params types.QueryDelegatorRewardsUnsyncedParams) (types.DelegatorClaims, error) {
|
||||
func executeSwapRewardsQuery(queryRoute string, cdc *codec.Codec, cliCtx context.CLIContext, params types.QueryRewardsParams) (types.SwapClaims, error) {
|
||||
bz, err := cdc.MarshalJSON(params)
|
||||
if err != nil {
|
||||
return types.DelegatorClaims{}, err
|
||||
return types.SwapClaims{}, err
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetDelegatorRewardsUnsynced)
|
||||
route := fmt.Sprintf("custom/%s/%s", queryRoute, types.QueryGetSwapRewards)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
if err != nil {
|
||||
return types.DelegatorClaims{}, err
|
||||
return types.SwapClaims{}, err
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
var claims types.DelegatorClaims
|
||||
var claims types.SwapClaims
|
||||
if err := cdc.UnmarshalJSON(res, &claims); err != nil {
|
||||
return types.DelegatorClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
|
||||
return types.SwapClaims{}, fmt.Errorf("failed to unmarshal claims: %w", err)
|
||||
}
|
||||
|
||||
return claims, nil
|
||||
|
@ -58,40 +58,18 @@ func queryRewardsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
}
|
||||
}
|
||||
|
||||
if unsynced {
|
||||
switch strings.ToLower(rewardType) {
|
||||
case "hard":
|
||||
params := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
|
||||
executeHardRewardsUnsyncedQuery(w, cliCtx, params)
|
||||
case "usdx_minting":
|
||||
params := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
|
||||
executeUSDXMintingRewardsUnsyncedQuery(w, cliCtx, params)
|
||||
case "delegator":
|
||||
params := types.NewQueryDelegatorRewardsUnsyncedParams(page, limit, owner)
|
||||
executeDelegatorRewardsUnsyncedQuery(w, cliCtx, params)
|
||||
default:
|
||||
hardParams := types.NewQueryHardRewardsUnsyncedParams(page, limit, owner)
|
||||
usdxMintingParams := types.NewQueryUSDXMintingRewardsUnsyncedParams(page, limit, owner)
|
||||
delegatorParams := types.NewQueryDelegatorRewardsUnsyncedParams(page, limit, owner)
|
||||
executeAllUnsyncedRewardQueries(w, cliCtx, hardParams, usdxMintingParams, delegatorParams)
|
||||
}
|
||||
} else {
|
||||
switch strings.ToLower(rewardType) {
|
||||
case "hard":
|
||||
params := types.NewQueryHardRewardsParams(page, limit, owner)
|
||||
executeHardRewardsQuery(w, cliCtx, params)
|
||||
case "usdx_minting":
|
||||
params := types.NewQueryUSDXMintingRewardsParams(page, limit, owner)
|
||||
executeUSDXMintingRewardsQuery(w, cliCtx, params)
|
||||
case "delegator":
|
||||
params := types.NewQueryDelegatorRewardsParams(page, limit, owner)
|
||||
executeDelegatorRewardsQuery(w, cliCtx, params)
|
||||
default:
|
||||
hardParams := types.NewQueryHardRewardsParams(page, limit, owner)
|
||||
usdxMintingParams := types.NewQueryUSDXMintingRewardsParams(page, limit, owner)
|
||||
delegatorParams := types.NewQueryDelegatorRewardsParams(page, limit, owner)
|
||||
executeAllRewardQueries(w, cliCtx, hardParams, usdxMintingParams, delegatorParams)
|
||||
}
|
||||
params := types.NewQueryRewardsParams(page, limit, owner, unsynced)
|
||||
switch strings.ToLower(rewardType) {
|
||||
case "hard":
|
||||
executeHardRewardsQuery(w, cliCtx, params)
|
||||
case "usdx_minting":
|
||||
executeUSDXMintingRewardsQuery(w, cliCtx, params)
|
||||
case "delegator":
|
||||
executeDelegatorRewardsQuery(w, cliCtx, params)
|
||||
case "swap":
|
||||
executeSwapRewardsQuery(w, cliCtx, params)
|
||||
default:
|
||||
executeAllRewardQueries(w, cliCtx, params)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,43 +96,25 @@ func queryParamsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
|
||||
func queryRewardFactorsHandlerFn(cliCtx context.CLIContext) http.HandlerFunc {
|
||||
return func(w http.ResponseWriter, r *http.Request) {
|
||||
_, _, _, err := rest.ParseHTTPArgsWithLimit(r, 0)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
// Parse the query height
|
||||
cliCtx, ok := rest.ParseQueryHeightOrReturnBadRequest(w, cliCtx, r)
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
||||
var denom string
|
||||
|
||||
if x := r.URL.Query().Get(RestDenom); len(x) != 0 {
|
||||
denom = strings.TrimSpace(x)
|
||||
}
|
||||
|
||||
params := types.NewQueryRewardFactorsParams(denom)
|
||||
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
route := fmt.Sprintf("custom/%s/%s", types.ModuleName, types.QueryGetRewardFactors)
|
||||
res, height, err := cliCtx.QueryWithData(route, bz)
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(route, nil)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
}
|
||||
|
||||
func executeHardRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryHardRewardsParams) {
|
||||
func executeHardRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryRewardsParams) {
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
@ -171,24 +131,7 @@ func executeHardRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, p
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
|
||||
func executeHardRewardsUnsyncedQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryHardRewardsUnsyncedParams) {
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetHardRewardsUnsynced), bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
|
||||
func executeUSDXMintingRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryUSDXMintingRewardsParams) {
|
||||
func executeUSDXMintingRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryRewardsParams) {
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
@ -205,24 +148,7 @@ func executeUSDXMintingRewardsQuery(w http.ResponseWriter, cliCtx context.CLICon
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
|
||||
func executeUSDXMintingRewardsUnsyncedQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryUSDXMintingRewardsUnsyncedParams) {
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetUSDXMintingRewardsUnsynced), bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
|
||||
func executeDelegatorRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryDelegatorRewardsParams) {
|
||||
func executeDelegatorRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryRewardsParams) {
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
@ -239,14 +165,14 @@ func executeDelegatorRewardsQuery(w http.ResponseWriter, cliCtx context.CLIConte
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
|
||||
func executeDelegatorRewardsUnsyncedQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryDelegatorRewardsUnsyncedParams) {
|
||||
func executeSwapRewardsQuery(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryRewardsParams) {
|
||||
bz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetDelegatorRewardsUnsynced), bz)
|
||||
res, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetSwapRewards), bz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@ -256,16 +182,14 @@ func executeDelegatorRewardsUnsyncedQuery(w http.ResponseWriter, cliCtx context.
|
||||
rest.PostProcessResponse(w, cliCtx, res)
|
||||
}
|
||||
|
||||
func executeAllRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext,
|
||||
hardParams types.QueryHardRewardsParams, usdxMintingParams types.QueryUSDXMintingRewardsParams,
|
||||
delegatorParams types.QueryDelegatorRewardsParams) {
|
||||
hardBz, err := cliCtx.Codec.MarshalJSON(hardParams)
|
||||
func executeAllRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext, params types.QueryRewardsParams) {
|
||||
|
||||
paramsBz, err := cliCtx.Codec.MarshalJSON(params)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
hardRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetHardRewards), hardBz)
|
||||
hardRes, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetHardRewards), paramsBz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@ -273,13 +197,7 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext,
|
||||
var hardClaims types.HardLiquidityProviderClaims
|
||||
cliCtx.Codec.MustUnmarshalJSON(hardRes, &hardClaims)
|
||||
|
||||
usdxMintingBz, err := cliCtx.Codec.MarshalJSON(usdxMintingParams)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
usdxMintingRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetUSDXMintingRewards), usdxMintingBz)
|
||||
usdxMintingRes, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetUSDXMintingRewards), paramsBz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@ -287,81 +205,7 @@ func executeAllRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext,
|
||||
var usdxMintingClaims types.USDXMintingClaims
|
||||
cliCtx.Codec.MustUnmarshalJSON(usdxMintingRes, &usdxMintingClaims)
|
||||
|
||||
delegatorBz, err := cliCtx.Codec.MarshalJSON(delegatorParams)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
delegatorRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetDelegatorRewards), delegatorBz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
var delegatorClaims types.DelegatorClaims
|
||||
cliCtx.Codec.MustUnmarshalJSON(delegatorRes, &delegatorClaims)
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
type rewardResult struct {
|
||||
HardClaims types.HardLiquidityProviderClaims `json:"hard_claims" yaml:"hard_claims"`
|
||||
UsdxMintingClaims types.USDXMintingClaims `json:"usdx_minting_claims" yaml:"usdx_minting_claims"`
|
||||
DelegatorClaims types.DelegatorClaims `json:"delegator_claims" yaml:"delegator_claims"`
|
||||
}
|
||||
|
||||
res := rewardResult{
|
||||
HardClaims: hardClaims,
|
||||
UsdxMintingClaims: usdxMintingClaims,
|
||||
DelegatorClaims: delegatorClaims,
|
||||
}
|
||||
|
||||
resBz, err := cliCtx.Codec.MarshalJSON(res)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal result: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
rest.PostProcessResponse(w, cliCtx, resBz)
|
||||
}
|
||||
|
||||
func executeAllUnsyncedRewardQueries(w http.ResponseWriter, cliCtx context.CLIContext,
|
||||
hardParams types.QueryHardRewardsUnsyncedParams, usdxMintingParams types.QueryUSDXMintingRewardsUnsyncedParams,
|
||||
delegatorParams types.QueryDelegatorRewardsUnsyncedParams) {
|
||||
hardBz, err := cliCtx.Codec.MarshalJSON(hardParams)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
hardRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetHardRewardsUnsynced), hardBz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
var hardClaims types.HardLiquidityProviderClaims
|
||||
cliCtx.Codec.MustUnmarshalJSON(hardRes, &hardClaims)
|
||||
|
||||
usdxMintingBz, err := cliCtx.Codec.MarshalJSON(usdxMintingParams)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
usdxMintingRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetUSDXMintingRewardsUnsynced), usdxMintingBz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
var usdxMintingClaims types.USDXMintingClaims
|
||||
cliCtx.Codec.MustUnmarshalJSON(usdxMintingRes, &usdxMintingClaims)
|
||||
|
||||
delegatorBz, err := cliCtx.Codec.MarshalJSON(delegatorParams)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusBadRequest, fmt.Sprintf("failed to marshal query params: %s", err))
|
||||
return
|
||||
}
|
||||
|
||||
delegatorRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetDelegatorRewardsUnsynced), delegatorBz)
|
||||
delegatorRes, _, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetDelegatorRewards), paramsBz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
@ -369,18 +213,28 @@ func executeAllUnsyncedRewardQueries(w http.ResponseWriter, cliCtx context.CLICo
|
||||
var delegatorClaims types.DelegatorClaims
|
||||
cliCtx.Codec.MustUnmarshalJSON(delegatorRes, &delegatorClaims)
|
||||
|
||||
swapRes, height, err := cliCtx.QueryWithData(fmt.Sprintf("custom/incentive/%s", types.QueryGetSwapRewards), paramsBz)
|
||||
if err != nil {
|
||||
rest.WriteErrorResponse(w, http.StatusInternalServerError, err.Error())
|
||||
return
|
||||
}
|
||||
var swapClaims types.SwapClaims
|
||||
cliCtx.Codec.MustUnmarshalJSON(swapRes, &swapClaims)
|
||||
|
||||
cliCtx = cliCtx.WithHeight(height)
|
||||
|
||||
type rewardResult struct {
|
||||
HardClaims types.HardLiquidityProviderClaims `json:"hard_claims" yaml:"hard_claims"`
|
||||
UsdxMintingClaims types.USDXMintingClaims `json:"usdx_minting_claims" yaml:"usdx_minting_claims"`
|
||||
DelegatorClaims types.DelegatorClaims `json:"delegator_claims" yaml:"delegator_claims"`
|
||||
SwapClaims types.SwapClaims `json:"swap_claims" yaml:"swap_claims"`
|
||||
}
|
||||
|
||||
res := rewardResult{
|
||||
HardClaims: hardClaims,
|
||||
UsdxMintingClaims: usdxMintingClaims,
|
||||
DelegatorClaims: delegatorClaims,
|
||||
SwapClaims: swapClaims,
|
||||
}
|
||||
|
||||
resBz, err := cliCtx.Codec.MarshalJSON(res)
|
||||
|
@ -115,6 +115,11 @@ func InitGenesis(ctx sdk.Context, k keeper.Keeper, supplyKeeper types.SupplyKeep
|
||||
}
|
||||
k.SetDelegatorClaim(ctx, claim)
|
||||
}
|
||||
|
||||
// TODO no synchronization of swap claims as it is about to be removed in a subsequent PR
|
||||
for _, claim := range gs.SwapClaims {
|
||||
k.SetSwapClaim(ctx, claim)
|
||||
}
|
||||
}
|
||||
|
||||
// ExportGenesis export genesis state for incentive module
|
||||
@ -124,10 +129,12 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
|
||||
usdxClaims := k.GetAllUSDXMintingClaims(ctx)
|
||||
hardClaims := k.GetAllHardLiquidityProviderClaims(ctx)
|
||||
delegatorClaims := k.GetAllDelegatorClaims(ctx)
|
||||
swapClaims := k.GetAllSwapClaims(ctx)
|
||||
|
||||
synchronizedUsdxClaims := types.USDXMintingClaims{}
|
||||
synchronizedHardClaims := types.HardLiquidityProviderClaims{}
|
||||
synchronizedDelegatorClaims := types.DelegatorClaims{}
|
||||
// TODO no synchronization of swap claims as it is about to be removed in a subsequent PR
|
||||
|
||||
for _, usdxClaim := range usdxClaims {
|
||||
claim, err := k.SynchronizeUSDXMintingClaim(ctx, usdxClaim)
|
||||
@ -222,7 +229,9 @@ func ExportGenesis(ctx sdk.Context, k keeper.Keeper) types.GenesisState {
|
||||
swapGats = append(swapGats, gat)
|
||||
}
|
||||
|
||||
return types.NewGenesisState(params, usdxMintingGats, hardSupplyGats,
|
||||
hardBorrowGats, delegatorGats, swapGats, synchronizedUsdxClaims,
|
||||
synchronizedHardClaims, synchronizedDelegatorClaims)
|
||||
return types.NewGenesisState(
|
||||
params,
|
||||
usdxMintingGats, hardSupplyGats, hardBorrowGats, delegatorGats, swapGats,
|
||||
synchronizedUsdxClaims, synchronizedHardClaims, synchronizedDelegatorClaims, swapClaims,
|
||||
)
|
||||
}
|
||||
|
@ -77,6 +77,7 @@ func (suite *GenesisTestSuite) SetupTest() {
|
||||
incentive.DefaultUSDXClaims,
|
||||
incentive.DefaultHardClaims,
|
||||
incentive.DefaultDelegatorClaims,
|
||||
incentive.DefaultSwapClaims,
|
||||
)
|
||||
tApp.InitializeFromGenesisStatesWithTime(
|
||||
suite.genesisTime,
|
||||
|
@ -60,6 +60,7 @@ func (suite *HandlerTestSuite) SetupTest() {
|
||||
incentive.DefaultUSDXClaims,
|
||||
incentive.DefaultHardClaims,
|
||||
incentive.DefaultDelegatorClaims,
|
||||
incentive.DefaultSwapClaims,
|
||||
)
|
||||
tApp.InitializeFromGenesisStates(authGS, app.GenesisState{incentive.ModuleName: incentive.ModuleCdc.MustMarshalJSON(incentiveGS)}, NewCDPGenStateMulti(), NewPricefeedGenStateMulti())
|
||||
|
||||
|
@ -6,6 +6,7 @@ import (
|
||||
|
||||
cdptypes "github.com/kava-labs/kava/x/cdp/types"
|
||||
hardtypes "github.com/kava-labs/kava/x/hard/types"
|
||||
swaptypes "github.com/kava-labs/kava/x/swap/types"
|
||||
)
|
||||
|
||||
// Hooks wrapper struct for hooks
|
||||
@ -16,6 +17,7 @@ type Hooks struct {
|
||||
var _ cdptypes.CDPHooks = Hooks{}
|
||||
var _ hardtypes.HARDHooks = Hooks{}
|
||||
var _ stakingtypes.StakingHooks = Hooks{}
|
||||
var _ swaptypes.SwapHooks = Hooks{}
|
||||
|
||||
// Hooks create new incentive hooks
|
||||
func (k Keeper) Hooks() Hooks { return Hooks{k} }
|
||||
@ -149,3 +151,13 @@ func (h Hooks) BeforeValidatorModified(ctx sdk.Context, valAddr sdk.ValAddress)
|
||||
// AfterValidatorRemoved runs after a validator is removed
|
||||
func (h Hooks) AfterValidatorRemoved(ctx sdk.Context, consAddr sdk.ConsAddress, valAddr sdk.ValAddress) {
|
||||
}
|
||||
|
||||
// ------------------- Swap Module Hooks -------------------
|
||||
|
||||
func (h Hooks) AfterPoolDepositCreated(ctx sdk.Context, poolID string, depositor sdk.AccAddress, _ sdk.Int) {
|
||||
h.k.InitializeSwapReward(ctx, poolID, depositor)
|
||||
}
|
||||
|
||||
func (h Hooks) BeforePoolDepositModified(ctx sdk.Context, poolID string, depositor sdk.AccAddress, sharesOwned sdk.Int) {
|
||||
h.k.SynchronizeSwapReward(ctx, poolID, depositor, sharesOwned)
|
||||
}
|
||||
|
@ -259,6 +259,55 @@ func (k Keeper) GetAllDelegatorClaims(ctx sdk.Context) types.DelegatorClaims {
|
||||
return cs
|
||||
}
|
||||
|
||||
// GetSwapClaim returns the claim in the store corresponding the the input address.
|
||||
func (k Keeper) GetSwapClaim(ctx sdk.Context, addr sdk.AccAddress) (types.SwapClaim, bool) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.SwapClaimKeyPrefix)
|
||||
bz := store.Get(addr)
|
||||
if bz == nil {
|
||||
return types.SwapClaim{}, false
|
||||
}
|
||||
var c types.SwapClaim
|
||||
k.cdc.MustUnmarshalBinaryBare(bz, &c)
|
||||
return c, true
|
||||
}
|
||||
|
||||
// SetSwapClaim sets the claim in the store corresponding to the input address.
|
||||
func (k Keeper) SetSwapClaim(ctx sdk.Context, c types.SwapClaim) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.SwapClaimKeyPrefix)
|
||||
bz := k.cdc.MustMarshalBinaryBare(c)
|
||||
store.Set(c.Owner, bz)
|
||||
}
|
||||
|
||||
// DeleteSwapClaim deletes the claim in the store corresponding to the input address.
|
||||
func (k Keeper) DeleteSwapClaim(ctx sdk.Context, owner sdk.AccAddress) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.SwapClaimKeyPrefix)
|
||||
store.Delete(owner)
|
||||
}
|
||||
|
||||
// IterateSwapClaims iterates over all claim objects in the store and preforms a callback function
|
||||
func (k Keeper) IterateSwapClaims(ctx sdk.Context, cb func(c types.SwapClaim) (stop bool)) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.SwapClaimKeyPrefix)
|
||||
iterator := sdk.KVStorePrefixIterator(store, []byte{})
|
||||
defer iterator.Close()
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
var c types.SwapClaim
|
||||
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &c)
|
||||
if cb(c) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetAllSwapClaims returns all Claim objects in the store
|
||||
func (k Keeper) GetAllSwapClaims(ctx sdk.Context) types.SwapClaims {
|
||||
cs := types.SwapClaims{}
|
||||
k.IterateSwapClaims(ctx, func(c types.SwapClaim) (stop bool) {
|
||||
cs = append(cs, c)
|
||||
return false
|
||||
})
|
||||
return cs
|
||||
}
|
||||
|
||||
// SetHardSupplyRewardIndexes sets the current reward indexes for an individual denom
|
||||
func (k Keeper) SetHardSupplyRewardIndexes(ctx sdk.Context, denom string, indexes types.RewardIndexes) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.HardSupplyRewardIndexesKeyPrefix)
|
||||
@ -428,6 +477,20 @@ func (k Keeper) GetSwapRewardIndexes(ctx sdk.Context, poolID string) (types.Rewa
|
||||
return rewardIndexes, true
|
||||
}
|
||||
|
||||
// IterateSwapRewardIndexes iterates over all swap reward index objects in the store and preforms a callback function
|
||||
func (k Keeper) IterateSwapRewardIndexes(ctx sdk.Context, cb func(poolID string, indexes types.RewardIndexes) (stop bool)) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.SwapRewardIndexesKeyPrefix)
|
||||
iterator := sdk.KVStorePrefixIterator(store, []byte{})
|
||||
defer iterator.Close()
|
||||
for ; iterator.Valid(); iterator.Next() {
|
||||
var indexes types.RewardIndexes
|
||||
k.cdc.MustUnmarshalBinaryBare(iterator.Value(), &indexes)
|
||||
if cb(string(iterator.Key()), indexes) {
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// GetSwapRewardAccrualTime fetches the last time rewards were accrued for a swap pool.
|
||||
func (k Keeper) GetSwapRewardAccrualTime(ctx sdk.Context, poolID string) (blockTime time.Time, found bool) {
|
||||
store := prefix.NewStore(ctx.KVStore(k.key), types.PreviousSwapRewardAccrualTimeKeyPrefix)
|
||||
|
@ -82,6 +82,46 @@ func (suite *KeeperTestSuite) TestIterateUSDXMintingClaims() {
|
||||
suite.Require().Equal(len(suite.addrs), len(claims))
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGetSetDeleteSwapClaims() {
|
||||
suite.SetupApp()
|
||||
c := types.NewSwapClaim(suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes)
|
||||
|
||||
_, found := suite.keeper.GetSwapClaim(suite.ctx, suite.addrs[0])
|
||||
suite.Require().False(found)
|
||||
|
||||
suite.Require().NotPanics(func() {
|
||||
suite.keeper.SetSwapClaim(suite.ctx, c)
|
||||
})
|
||||
testC, found := suite.keeper.GetSwapClaim(suite.ctx, suite.addrs[0])
|
||||
suite.Require().True(found)
|
||||
suite.Require().Equal(c, testC)
|
||||
|
||||
suite.Require().NotPanics(func() {
|
||||
suite.keeper.DeleteSwapClaim(suite.ctx, suite.addrs[0])
|
||||
})
|
||||
_, found = suite.keeper.GetSwapClaim(suite.ctx, suite.addrs[0])
|
||||
suite.Require().False(found)
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestIterateSwapClaims() {
|
||||
suite.SetupApp()
|
||||
claims := types.SwapClaims{
|
||||
types.NewSwapClaim(suite.addrs[0], arbitraryCoins(), nonEmptyMultiRewardIndexes),
|
||||
types.NewSwapClaim(suite.addrs[1], nil, nil), // different claim to the first
|
||||
}
|
||||
for _, claim := range claims {
|
||||
suite.keeper.SetSwapClaim(suite.ctx, claim)
|
||||
}
|
||||
|
||||
var actualClaims types.SwapClaims
|
||||
suite.keeper.IterateSwapClaims(suite.ctx, func(c types.SwapClaim) bool {
|
||||
actualClaims = append(actualClaims, c)
|
||||
return false
|
||||
})
|
||||
|
||||
suite.Require().Equal(claims, actualClaims)
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGetSetSwapRewardIndexes() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
@ -155,6 +195,45 @@ func (suite *KeeperTestSuite) TestGetSetSwapRewardIndexes() {
|
||||
}
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestIterateSwapRewardIndexes() {
|
||||
suite.SetupApp()
|
||||
multiIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: "bnb/usdx",
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "swap",
|
||||
RewardFactor: d("0.0000002"),
|
||||
},
|
||||
{
|
||||
CollateralType: "ukava",
|
||||
RewardFactor: d("0.04"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
CollateralType: "btcb/usdx",
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "hard",
|
||||
RewardFactor: d("0.02"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
for _, mi := range multiIndexes {
|
||||
suite.keeper.SetSwapRewardIndexes(suite.ctx, mi.CollateralType, mi.RewardIndexes)
|
||||
}
|
||||
|
||||
var actualMultiIndexes types.MultiRewardIndexes
|
||||
suite.keeper.IterateSwapRewardIndexes(suite.ctx, func(poolID string, i types.RewardIndexes) bool {
|
||||
actualMultiIndexes = actualMultiIndexes.With(poolID, i)
|
||||
return false
|
||||
})
|
||||
|
||||
suite.Require().Equal(multiIndexes, actualMultiIndexes)
|
||||
}
|
||||
|
||||
func (suite *KeeperTestSuite) TestGetSetSwapRewardAccrualTimes() {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
@ -17,18 +17,16 @@ func NewQuerier(k Keeper) sdk.Querier {
|
||||
switch path[0] {
|
||||
case types.QueryGetParams:
|
||||
return queryGetParams(ctx, req, k)
|
||||
|
||||
case types.QueryGetHardRewards:
|
||||
return queryGetHardRewards(ctx, req, k)
|
||||
case types.QueryGetHardRewardsUnsynced:
|
||||
return queryGetHardRewardsUnsynced(ctx, req, k)
|
||||
case types.QueryGetUSDXMintingRewards:
|
||||
return queryGetUSDXMintingRewards(ctx, req, k)
|
||||
case types.QueryGetUSDXMintingRewardsUnsynced:
|
||||
return queryGetUSDXMintingRewardsUnsynced(ctx, req, k)
|
||||
case types.QueryGetDelegatorRewards:
|
||||
return queryGetDelegatorRewards(ctx, req, k)
|
||||
case types.QueryGetDelegatorRewardsUnsynced:
|
||||
return queryGetDelegatorRewardsUnsynced(ctx, req, k)
|
||||
case types.QueryGetSwapRewards:
|
||||
return queryGetSwapRewards(ctx, req, k)
|
||||
|
||||
case types.QueryGetRewardFactors:
|
||||
return queryGetRewardFactors(ctx, req, k)
|
||||
default:
|
||||
@ -51,7 +49,7 @@ func queryGetParams(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, e
|
||||
}
|
||||
|
||||
func queryGetHardRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryHardRewardsParams
|
||||
var params types.QueryRewardsParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
@ -77,45 +75,10 @@ func queryGetHardRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]by
|
||||
paginatedHardClaims = hardClaims[startH:endH]
|
||||
}
|
||||
|
||||
var augmentedHardClaims types.HardLiquidityProviderClaims
|
||||
for _, claim := range paginatedHardClaims {
|
||||
augmentedClaim := k.SimulateHardSynchronization(ctx, claim)
|
||||
augmentedHardClaims = append(augmentedHardClaims, augmentedClaim)
|
||||
}
|
||||
|
||||
// Marshal Hard claims
|
||||
bz, err := codec.MarshalJSONIndent(k.cdc, augmentedHardClaims)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetHardRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryHardRewardsUnsyncedParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
owner := len(params.Owner) > 0
|
||||
|
||||
var hardClaims types.HardLiquidityProviderClaims
|
||||
switch {
|
||||
case owner:
|
||||
hardClaim, foundHardClaim := k.GetHardLiquidityProviderClaim(ctx, params.Owner)
|
||||
if foundHardClaim {
|
||||
hardClaims = append(hardClaims, hardClaim)
|
||||
if !params.Unsynchronized {
|
||||
for i, claim := range paginatedHardClaims {
|
||||
paginatedHardClaims[i] = k.SimulateHardSynchronization(ctx, claim)
|
||||
}
|
||||
default:
|
||||
hardClaims = k.GetAllHardLiquidityProviderClaims(ctx)
|
||||
}
|
||||
|
||||
var paginatedHardClaims types.HardLiquidityProviderClaims
|
||||
startH, endH := client.Paginate(len(hardClaims), params.Page, params.Limit, 100)
|
||||
if startH < 0 || endH < 0 {
|
||||
paginatedHardClaims = types.HardLiquidityProviderClaims{}
|
||||
} else {
|
||||
paginatedHardClaims = hardClaims[startH:endH]
|
||||
}
|
||||
|
||||
// Marshal Hard claims
|
||||
@ -127,7 +90,7 @@ func queryGetHardRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery, k Keepe
|
||||
}
|
||||
|
||||
func queryGetUSDXMintingRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryUSDXMintingRewardsParams
|
||||
var params types.QueryRewardsParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
@ -153,45 +116,10 @@ func queryGetUSDXMintingRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper
|
||||
paginatedUsdxMintingClaims = usdxMintingClaims[startU:endU]
|
||||
}
|
||||
|
||||
var augmentedUsdxMintingClaims types.USDXMintingClaims
|
||||
for _, claim := range paginatedUsdxMintingClaims {
|
||||
augmentedClaim := k.SimulateUSDXMintingSynchronization(ctx, claim)
|
||||
augmentedUsdxMintingClaims = append(augmentedUsdxMintingClaims, augmentedClaim)
|
||||
}
|
||||
|
||||
// Marshal USDX minting claims
|
||||
bz, err := codec.MarshalJSONIndent(k.cdc, augmentedUsdxMintingClaims)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetUSDXMintingRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryUSDXMintingRewardsUnsyncedParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
owner := len(params.Owner) > 0
|
||||
|
||||
var usdxMintingClaims types.USDXMintingClaims
|
||||
switch {
|
||||
case owner:
|
||||
usdxMintingClaim, foundUsdxMintingClaim := k.GetUSDXMintingClaim(ctx, params.Owner)
|
||||
if foundUsdxMintingClaim {
|
||||
usdxMintingClaims = append(usdxMintingClaims, usdxMintingClaim)
|
||||
if !params.Unsynchronized {
|
||||
for i, claim := range paginatedUsdxMintingClaims {
|
||||
paginatedUsdxMintingClaims[i] = k.SimulateUSDXMintingSynchronization(ctx, claim)
|
||||
}
|
||||
default:
|
||||
usdxMintingClaims = k.GetAllUSDXMintingClaims(ctx)
|
||||
}
|
||||
|
||||
var paginatedUsdxMintingClaims types.USDXMintingClaims
|
||||
startU, endU := client.Paginate(len(usdxMintingClaims), params.Page, params.Limit, 100)
|
||||
if startU < 0 || endU < 0 {
|
||||
paginatedUsdxMintingClaims = types.USDXMintingClaims{}
|
||||
} else {
|
||||
paginatedUsdxMintingClaims = usdxMintingClaims[startU:endU]
|
||||
}
|
||||
|
||||
// Marshal USDX minting claims
|
||||
@ -203,7 +131,7 @@ func queryGetUSDXMintingRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery,
|
||||
}
|
||||
|
||||
func queryGetDelegatorRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryDelegatorRewardsParams
|
||||
var params types.QueryRewardsParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
@ -229,45 +157,10 @@ func queryGetDelegatorRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper)
|
||||
paginatedDelegatorClaims = delegatorClaims[startH:endH]
|
||||
}
|
||||
|
||||
var augmentedDelegatorClaims types.DelegatorClaims
|
||||
for _, claim := range paginatedDelegatorClaims {
|
||||
augmentedClaim := k.SimulateDelegatorSynchronization(ctx, claim)
|
||||
augmentedDelegatorClaims = append(augmentedDelegatorClaims, augmentedClaim)
|
||||
}
|
||||
|
||||
// Marshal Hard claims
|
||||
bz, err := codec.MarshalJSONIndent(k.cdc, augmentedDelegatorClaims)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetDelegatorRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryDelegatorRewardsUnsyncedParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
owner := len(params.Owner) > 0
|
||||
|
||||
var delegatorClaims types.DelegatorClaims
|
||||
switch {
|
||||
case owner:
|
||||
delegatorClaim, foundHardClaim := k.GetDelegatorClaim(ctx, params.Owner)
|
||||
if foundHardClaim {
|
||||
delegatorClaims = append(delegatorClaims, delegatorClaim)
|
||||
if !params.Unsynchronized {
|
||||
for i, claim := range paginatedDelegatorClaims {
|
||||
paginatedDelegatorClaims[i] = k.SimulateDelegatorSynchronization(ctx, claim)
|
||||
}
|
||||
default:
|
||||
delegatorClaims = k.GetAllDelegatorClaims(ctx)
|
||||
}
|
||||
|
||||
var paginatedDelegatorClaims types.DelegatorClaims
|
||||
startH, endH := client.Paginate(len(delegatorClaims), params.Page, params.Limit, 100)
|
||||
if startH < 0 || endH < 0 {
|
||||
paginatedDelegatorClaims = types.DelegatorClaims{}
|
||||
} else {
|
||||
paginatedDelegatorClaims = delegatorClaims[startH:endH]
|
||||
}
|
||||
|
||||
// Marshal Hard claims
|
||||
@ -278,89 +171,92 @@ func queryGetDelegatorRewardsUnsynced(ctx sdk.Context, req abci.RequestQuery, k
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryRewardFactorsParams
|
||||
func queryGetSwapRewards(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
var params types.QueryRewardsParams
|
||||
err := types.ModuleCdc.UnmarshalJSON(req.Data, ¶ms)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONUnmarshal, err.Error())
|
||||
}
|
||||
owner := len(params.Owner) > 0
|
||||
|
||||
var rewardFactors types.RewardFactors
|
||||
if len(params.Denom) > 0 {
|
||||
// Fetch reward factors for a single denom
|
||||
rewardFactor := types.RewardFactor{}
|
||||
rewardFactor.Denom = params.Denom
|
||||
var claims types.SwapClaims
|
||||
switch {
|
||||
case owner:
|
||||
claim, found := k.GetSwapClaim(ctx, params.Owner)
|
||||
if found {
|
||||
claims = append(claims, claim)
|
||||
}
|
||||
default:
|
||||
claims = k.GetAllSwapClaims(ctx)
|
||||
}
|
||||
|
||||
usdxMintingRewardFactor, found := k.GetUSDXMintingRewardFactor(ctx, params.Denom)
|
||||
if found {
|
||||
rewardFactor.USDXMintingRewardFactor = usdxMintingRewardFactor
|
||||
}
|
||||
hardSupplyRewardIndexes, found := k.GetHardSupplyRewardIndexes(ctx, params.Denom)
|
||||
if found {
|
||||
rewardFactor.HardSupplyRewardFactors = hardSupplyRewardIndexes
|
||||
}
|
||||
hardBorrowRewardIndexes, found := k.GetHardBorrowRewardIndexes(ctx, params.Denom)
|
||||
if found {
|
||||
rewardFactor.HardBorrowRewardFactors = hardBorrowRewardIndexes
|
||||
}
|
||||
delegatorRewardIndexes, found := k.GetDelegatorRewardIndexes(ctx, params.Denom)
|
||||
if found {
|
||||
rewardFactor.DelegatorRewardFactors = delegatorRewardIndexes
|
||||
}
|
||||
rewardFactors = append(rewardFactors, rewardFactor)
|
||||
var paginatedClaims types.SwapClaims
|
||||
startH, endH := client.Paginate(len(claims), params.Page, params.Limit, 100)
|
||||
if startH < 0 || endH < 0 {
|
||||
paginatedClaims = types.SwapClaims{}
|
||||
} else {
|
||||
rewardFactorMap := make(map[string]types.RewardFactor)
|
||||
paginatedClaims = claims[startH:endH]
|
||||
}
|
||||
|
||||
// Populate mapping with usdx minting reward factors
|
||||
k.IterateUSDXMintingRewardFactors(ctx, func(denom string, factor sdk.Dec) (stop bool) {
|
||||
rewardFactor := types.RewardFactor{Denom: denom, USDXMintingRewardFactor: factor}
|
||||
rewardFactorMap[denom] = rewardFactor
|
||||
return false
|
||||
})
|
||||
|
||||
// Populate mapping with Hard supply reward factors
|
||||
k.IterateHardSupplyRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
|
||||
rewardFactor, ok := rewardFactorMap[denom]
|
||||
if !ok {
|
||||
rewardFactor = types.RewardFactor{Denom: denom, HardSupplyRewardFactors: indexes}
|
||||
} else {
|
||||
rewardFactor.HardSupplyRewardFactors = indexes
|
||||
if !params.Unsynchronized {
|
||||
for i, claim := range paginatedClaims {
|
||||
syncedClaim, found := k.GetSynchronizedSwapClaim(ctx, claim.Owner)
|
||||
if !found {
|
||||
panic("previously found claim should still be found")
|
||||
}
|
||||
rewardFactorMap[denom] = rewardFactor
|
||||
return false
|
||||
})
|
||||
|
||||
// Populate mapping with Hard borrow reward factors
|
||||
k.IterateHardBorrowRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
|
||||
rewardFactor, ok := rewardFactorMap[denom]
|
||||
if !ok {
|
||||
rewardFactor = types.RewardFactor{Denom: denom, HardBorrowRewardFactors: indexes}
|
||||
} else {
|
||||
rewardFactor.HardBorrowRewardFactors = indexes
|
||||
}
|
||||
rewardFactorMap[denom] = rewardFactor
|
||||
return false
|
||||
})
|
||||
|
||||
// Populate mapping with delegator reward factors
|
||||
k.IterateDelegatorRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
|
||||
rewardFactor, ok := rewardFactorMap[denom]
|
||||
if !ok {
|
||||
rewardFactor = types.RewardFactor{Denom: denom, DelegatorRewardFactors: indexes}
|
||||
} else {
|
||||
rewardFactor.DelegatorRewardFactors = indexes
|
||||
}
|
||||
rewardFactorMap[denom] = rewardFactor
|
||||
return false
|
||||
})
|
||||
|
||||
// Translate mapping to slice
|
||||
for _, val := range rewardFactorMap {
|
||||
rewardFactors = append(rewardFactors, val)
|
||||
paginatedClaims[i] = syncedClaim
|
||||
}
|
||||
}
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, rewardFactors)
|
||||
// Marshal claims
|
||||
bz, err := codec.MarshalJSONIndent(k.cdc, paginatedClaims)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
return bz, nil
|
||||
}
|
||||
|
||||
func queryGetRewardFactors(ctx sdk.Context, req abci.RequestQuery, k Keeper) ([]byte, error) {
|
||||
|
||||
var usdxFactors types.RewardIndexes
|
||||
k.IterateUSDXMintingRewardFactors(ctx, func(collateralType string, factor sdk.Dec) (stop bool) {
|
||||
usdxFactors = usdxFactors.With(collateralType, factor)
|
||||
return false
|
||||
})
|
||||
|
||||
var supplyFactors types.MultiRewardIndexes
|
||||
k.IterateHardSupplyRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
|
||||
supplyFactors = supplyFactors.With(denom, indexes)
|
||||
return false
|
||||
})
|
||||
|
||||
var borrowFactors types.MultiRewardIndexes
|
||||
k.IterateHardBorrowRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
|
||||
borrowFactors = borrowFactors.With(denom, indexes)
|
||||
return false
|
||||
})
|
||||
|
||||
var delegatorFactors types.MultiRewardIndexes
|
||||
k.IterateDelegatorRewardIndexes(ctx, func(denom string, indexes types.RewardIndexes) (stop bool) {
|
||||
delegatorFactors = delegatorFactors.With(denom, indexes)
|
||||
return false
|
||||
})
|
||||
|
||||
var swapFactors types.MultiRewardIndexes
|
||||
k.IterateSwapRewardIndexes(ctx, func(poolID string, indexes types.RewardIndexes) (stop bool) {
|
||||
swapFactors = swapFactors.With(poolID, indexes)
|
||||
return false
|
||||
})
|
||||
|
||||
response := types.NewQueryGetRewardFactorsResponse(
|
||||
usdxFactors,
|
||||
supplyFactors,
|
||||
borrowFactors,
|
||||
delegatorFactors,
|
||||
swapFactors,
|
||||
)
|
||||
|
||||
bz, err := codec.MarshalJSONIndent(types.ModuleCdc, response)
|
||||
if err != nil {
|
||||
return nil, sdkerrors.Wrap(sdkerrors.ErrJSONMarshal, err.Error())
|
||||
}
|
||||
|
@ -1,6 +1,8 @@
|
||||
package keeper
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/kava-labs/kava/x/incentive/types"
|
||||
@ -24,10 +26,10 @@ func (k Keeper) AccumulateSwapRewards(ctx sdk.Context, rewardPeriod types.MultiR
|
||||
|
||||
totalShares, found := k.swapKeeper.GetPoolShares(ctx, rewardPeriod.CollateralType)
|
||||
if !found {
|
||||
totalShares = sdk.ZeroDec()
|
||||
totalShares = sdk.ZeroInt()
|
||||
}
|
||||
|
||||
acc.Accumulate(rewardPeriod, totalShares, ctx.BlockTime())
|
||||
acc.Accumulate(rewardPeriod, totalShares.ToDec(), ctx.BlockTime())
|
||||
|
||||
k.SetSwapRewardAccrualTime(ctx, rewardPeriod.CollateralType, acc.PreviousAccumulationTime)
|
||||
if len(acc.Indexes) > 0 {
|
||||
@ -35,3 +37,85 @@ func (k Keeper) AccumulateSwapRewards(ctx sdk.Context, rewardPeriod types.MultiR
|
||||
k.SetSwapRewardIndexes(ctx, rewardPeriod.CollateralType, acc.Indexes)
|
||||
}
|
||||
}
|
||||
|
||||
// InitializeSwapReward creates a new claim with zero rewards and indexes matching the global indexes.
|
||||
// If the claim already exists it just updates the indexes.
|
||||
func (k Keeper) InitializeSwapReward(ctx sdk.Context, poolID string, owner sdk.AccAddress) {
|
||||
claim, found := k.GetSwapClaim(ctx, owner)
|
||||
if !found {
|
||||
claim = types.NewSwapClaim(owner, sdk.Coins{}, nil)
|
||||
}
|
||||
|
||||
globalRewardIndexes, found := k.GetSwapRewardIndexes(ctx, poolID)
|
||||
if !found {
|
||||
globalRewardIndexes = types.RewardIndexes{}
|
||||
}
|
||||
claim.RewardIndexes = claim.RewardIndexes.With(poolID, globalRewardIndexes)
|
||||
|
||||
k.SetSwapClaim(ctx, claim)
|
||||
}
|
||||
|
||||
// SynchronizeSwapReward updates the claim object by adding any accumulated rewards
|
||||
// and updating the reward index value.
|
||||
func (k Keeper) SynchronizeSwapReward(ctx sdk.Context, poolID string, owner sdk.AccAddress, shares sdk.Int) {
|
||||
claim, found := k.GetSwapClaim(ctx, owner)
|
||||
if !found {
|
||||
return
|
||||
}
|
||||
claim = k.synchronizeSwapReward(ctx, claim, poolID, owner, shares)
|
||||
|
||||
k.SetSwapClaim(ctx, claim)
|
||||
}
|
||||
|
||||
// synchronizeSwapReward updates the reward in a swap claim for one pool.
|
||||
func (k *Keeper) synchronizeSwapReward(ctx sdk.Context, claim types.SwapClaim, poolID string, owner sdk.AccAddress, shares sdk.Int) types.SwapClaim {
|
||||
globalRewardIndexes, found := k.GetSwapRewardIndexes(ctx, poolID)
|
||||
if !found {
|
||||
// The global factor is only not found if
|
||||
// - the pool has not started accumulating rewards yet (either there is no reward specified in params, or the reward start time hasn't been hit)
|
||||
// - OR it was wrongly deleted from state (factors should never be removed while unsynced claims exist)
|
||||
// If not found we could either skip this sync, or assume the global factor is zero.
|
||||
// Skipping will avoid storing unnecessary factors in the claim for non rewarded pools.
|
||||
// And in the event a global factor is wrongly deleted, it will avoid this function panicking when calculating rewards.
|
||||
return claim
|
||||
}
|
||||
|
||||
userRewardIndexes, found := claim.RewardIndexes.Get(poolID)
|
||||
if !found {
|
||||
// Normally the reward indexes should always be found.
|
||||
// But if a pool was not rewarded then becomes rewarded (ie a reward period is added to params), then the indexes will be missing from claims for that pool.
|
||||
// So given the reward period was just added, assume the starting value for any global reward indexes, which is an empty slice.
|
||||
userRewardIndexes = types.RewardIndexes{}
|
||||
}
|
||||
|
||||
newRewards, err := k.CalculateRewards(userRewardIndexes, globalRewardIndexes, shares.ToDec())
|
||||
if err != nil {
|
||||
// Global reward factors should never decrease, as it would lead to a negative update to claim.Rewards.
|
||||
// This panics if a global reward factor decreases or disappears between the old and new indexes.
|
||||
panic(fmt.Sprintf("corrupted global reward indexes found: %v", err))
|
||||
}
|
||||
|
||||
claim.Reward = claim.Reward.Add(newRewards...)
|
||||
claim.RewardIndexes = claim.RewardIndexes.With(poolID, globalRewardIndexes)
|
||||
|
||||
return claim
|
||||
}
|
||||
|
||||
// GetSynchronizedSwapClaim fetches a swap claim from the store and syncs rewards for all pools.
|
||||
func (k Keeper) GetSynchronizedSwapClaim(ctx sdk.Context, owner sdk.AccAddress) (types.SwapClaim, bool) {
|
||||
claim, found := k.GetSwapClaim(ctx, owner)
|
||||
if !found {
|
||||
return types.SwapClaim{}, false
|
||||
}
|
||||
for _, indexes := range claim.RewardIndexes {
|
||||
poolID := indexes.CollateralType
|
||||
|
||||
shares, found := k.swapKeeper.GetDepositorSharesInPool(ctx, owner, poolID)
|
||||
if !found {
|
||||
shares = sdk.ZeroInt()
|
||||
}
|
||||
|
||||
claim = k.synchronizeSwapReward(ctx, claim, poolID, owner, shares)
|
||||
}
|
||||
return claim, true
|
||||
}
|
||||
|
195
x/incentive/keeper/rewards_swap_init_test.go
Normal file
195
x/incentive/keeper/rewards_swap_init_test.go
Normal file
@ -0,0 +1,195 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/kava-labs/kava/x/incentive/types"
|
||||
)
|
||||
|
||||
// InitializeSwapRewardTests runs unit tests for the keeper.InitializeSwapReward method
|
||||
//
|
||||
// inputs
|
||||
// - claim in store if it exists
|
||||
// - global indexes in store
|
||||
//
|
||||
// outputs
|
||||
// - sets or creates a claim
|
||||
type InitializeSwapRewardTests struct {
|
||||
unitTester
|
||||
}
|
||||
|
||||
func TestInitializeSwapReward(t *testing.T) {
|
||||
suite.Run(t, new(InitializeSwapRewardTests))
|
||||
}
|
||||
|
||||
func (suite *InitializeSwapRewardTests) TestClaimAddedWhenClaimDoesNotExistAndNoRewards() {
|
||||
// When a claim doesn't exist, and a user deposits to a non-rewarded pool;
|
||||
// then a claim is added with no rewards and no indexes
|
||||
|
||||
poolID := "base/quote"
|
||||
|
||||
// no global indexes stored as this pool is not rewarded
|
||||
|
||||
owner := arbitraryAddress()
|
||||
|
||||
suite.keeper.InitializeSwapReward(suite.ctx, poolID, owner)
|
||||
|
||||
syncedClaim, found := suite.keeper.GetSwapClaim(suite.ctx, owner)
|
||||
suite.True(found)
|
||||
// A new claim should have empty indexes. It doesn't strictly need the poolID either.
|
||||
expectedIndexes := types.MultiRewardIndexes{{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: nil,
|
||||
}}
|
||||
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
|
||||
// a new claim should start with 0 rewards
|
||||
suite.Equal(sdk.Coins(nil), syncedClaim.Reward)
|
||||
}
|
||||
|
||||
func (suite *InitializeSwapRewardTests) TestClaimAddedWhenClaimDoesNotExistAndRewardsExist() {
|
||||
// When a claim doesn't exist, and a user deposits to a rewarded pool;
|
||||
// then a claim is added with no rewards and indexes matching the global indexes
|
||||
|
||||
poolID := "base/quote"
|
||||
|
||||
globalIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeGlobalSwapIndexes(globalIndexes)
|
||||
|
||||
owner := arbitraryAddress()
|
||||
|
||||
suite.keeper.InitializeSwapReward(suite.ctx, poolID, owner)
|
||||
|
||||
syncedClaim, found := suite.keeper.GetSwapClaim(suite.ctx, owner)
|
||||
suite.True(found)
|
||||
// a new claim should start with the current global indexes
|
||||
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
|
||||
// a new claim should start with 0 rewards
|
||||
suite.Equal(sdk.Coins(nil), syncedClaim.Reward)
|
||||
}
|
||||
|
||||
func (suite *InitializeSwapRewardTests) TestClaimUpdatedWhenClaimExistsAndNoRewards() {
|
||||
// When a claim exists, and a user deposits to a new non-rewarded pool;
|
||||
// then the claim's rewards don't change
|
||||
|
||||
preexistingPoolID := "preexisting"
|
||||
preexistingIndexes := types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
}
|
||||
|
||||
newPoolID := "btcb/usdx"
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: arbitraryCoins(),
|
||||
},
|
||||
RewardIndexes: types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: preexistingPoolID,
|
||||
RewardIndexes: preexistingIndexes,
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
// no global indexes stored as the new pool is not rewarded
|
||||
|
||||
suite.keeper.InitializeSwapReward(suite.ctx, newPoolID, claim.Owner)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
// The preexisting indexes shouldn't be changed. It doesn't strictly need the new poolID either.
|
||||
expectedIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: preexistingPoolID,
|
||||
RewardIndexes: preexistingIndexes,
|
||||
},
|
||||
{
|
||||
CollateralType: newPoolID,
|
||||
RewardIndexes: nil,
|
||||
},
|
||||
}
|
||||
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
|
||||
// init should never alter the rewards
|
||||
suite.Equal(claim.Reward, syncedClaim.Reward)
|
||||
}
|
||||
|
||||
func (suite *InitializeSwapRewardTests) TestClaimUpdatedWhenClaimExistsAndRewardsExist() {
|
||||
// When a claim exists, and a user deposits to a new rewarded pool;
|
||||
// then the claim's rewards don't change and the indexes are updated to match the global indexes
|
||||
|
||||
preexistingPoolID := "preexisting"
|
||||
preexistingIndexes := types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
}
|
||||
|
||||
newPoolID := "btcb/usdx"
|
||||
newIndexes := types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "otherrewarddenom",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
}
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: arbitraryCoins(),
|
||||
},
|
||||
RewardIndexes: types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: preexistingPoolID,
|
||||
RewardIndexes: preexistingIndexes,
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
globalIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: preexistingPoolID,
|
||||
RewardIndexes: increaseRewardFactors(preexistingIndexes),
|
||||
},
|
||||
{
|
||||
CollateralType: newPoolID,
|
||||
RewardIndexes: newIndexes,
|
||||
},
|
||||
}
|
||||
suite.storeGlobalSwapIndexes(globalIndexes)
|
||||
|
||||
suite.keeper.InitializeSwapReward(suite.ctx, newPoolID, claim.Owner)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
// only the indexes for the new pool should be updated
|
||||
expectedIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: preexistingPoolID,
|
||||
RewardIndexes: preexistingIndexes,
|
||||
},
|
||||
{
|
||||
CollateralType: newPoolID,
|
||||
RewardIndexes: newIndexes,
|
||||
},
|
||||
}
|
||||
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
|
||||
// init should never alter the rewards
|
||||
suite.Equal(claim.Reward, syncedClaim.Reward)
|
||||
}
|
317
x/incentive/keeper/rewards_swap_sync_test.go
Normal file
317
x/incentive/keeper/rewards_swap_sync_test.go
Normal file
@ -0,0 +1,317 @@
|
||||
package keeper_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/suite"
|
||||
|
||||
"github.com/kava-labs/kava/x/incentive/types"
|
||||
)
|
||||
|
||||
// SynchronizeSwapRewardTests runs unit tests for the keeper.SynchronizeSwapReward method
|
||||
//
|
||||
// inputs
|
||||
// - claim in store (only claim.RewardIndexes, claim.Reward)
|
||||
// - global indexes in store
|
||||
// - shares function arg
|
||||
//
|
||||
// outputs
|
||||
// - sets a claim
|
||||
type SynchronizeSwapRewardTests struct {
|
||||
unitTester
|
||||
}
|
||||
|
||||
func TestSynchronizeSwapReward(t *testing.T) {
|
||||
suite.Run(t, new(SynchronizeSwapRewardTests))
|
||||
}
|
||||
|
||||
func (suite *SynchronizeSwapRewardTests) TestClaimUpdatedWhenGlobalIndexesHaveIncreased() {
|
||||
// This is the normal case
|
||||
// Given some time has passed (meaning the global indexes have increased)
|
||||
// When the claim is synced
|
||||
// The user earns rewards for the time passed, and the claim indexes are updated
|
||||
|
||||
originalReward := arbitraryCoins()
|
||||
poolID := "base/quote"
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: originalReward,
|
||||
},
|
||||
RewardIndexes: types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
globalIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("2000.002"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeGlobalSwapIndexes(globalIndexes)
|
||||
|
||||
userShares := i(1e9)
|
||||
|
||||
suite.keeper.SynchronizeSwapReward(suite.ctx, poolID, claim.Owner, userShares)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
// indexes updated from global
|
||||
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
|
||||
// new reward is (new index - old index) * user shares
|
||||
suite.Equal(
|
||||
cs(c("rewarddenom", 1_000_001_000_000)).Add(originalReward...),
|
||||
syncedClaim.Reward,
|
||||
)
|
||||
}
|
||||
|
||||
func (suite *SynchronizeSwapRewardTests) TestClaimUnchangedWhenGlobalIndexesUnchanged() {
|
||||
// It should be safe to call SynchronizeSwapReward multiple times
|
||||
|
||||
poolID := "base/quote"
|
||||
unchangingIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: arbitraryCoins(),
|
||||
},
|
||||
RewardIndexes: unchangingIndexes,
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
suite.storeGlobalSwapIndexes(unchangingIndexes)
|
||||
|
||||
userShares := i(1e9)
|
||||
|
||||
suite.keeper.SynchronizeSwapReward(suite.ctx, poolID, claim.Owner, userShares)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
// claim should have the same rewards and indexes as before
|
||||
suite.Equal(claim, syncedClaim)
|
||||
}
|
||||
func (suite *SynchronizeSwapRewardTests) TestClaimUpdatedWhenNewRewardAdded() {
|
||||
// When a new reward is added (via gov) for a pool the user has already deposited to, and the claim is synced;
|
||||
// Then the user earns rewards for the time since the reward was added, and the indexes are added to the claim.
|
||||
|
||||
originalReward := arbitraryCoins()
|
||||
newlyRewardPoolID := "newlyRewardedPool"
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: originalReward,
|
||||
},
|
||||
RewardIndexes: types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: "currentlyRewardedPool",
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "reward",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
globalIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: "currentlyRewardedPool",
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "reward",
|
||||
RewardFactor: d("2000.002"),
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
CollateralType: newlyRewardPoolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "otherreward",
|
||||
// Indexes start at 0 when the reward is added by gov,
|
||||
// so this represents the syncing happening some time later.
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeGlobalSwapIndexes(globalIndexes)
|
||||
|
||||
userShares := i(1e9)
|
||||
|
||||
suite.keeper.SynchronizeSwapReward(suite.ctx, newlyRewardPoolID, claim.Owner, userShares)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
// the new indexes should be added to the claim, but the old ones should be unchanged
|
||||
newlyRewrdedIndexes, _ := globalIndexes.Get(newlyRewardPoolID)
|
||||
expectedIndexes := claim.RewardIndexes.With(newlyRewardPoolID, newlyRewrdedIndexes)
|
||||
suite.Equal(expectedIndexes, syncedClaim.RewardIndexes)
|
||||
// new reward is (new index - old index) * shares for the synced pool
|
||||
// The old index for `newlyrewarded` isn't in the claim, so it's added starting at 0 for calculating the reward.
|
||||
suite.Equal(
|
||||
cs(c("otherreward", 1_000_001_000_000)).Add(originalReward...),
|
||||
syncedClaim.Reward,
|
||||
)
|
||||
}
|
||||
|
||||
func (suite *SynchronizeSwapRewardTests) TestClaimUnchangedWhenNoReward() {
|
||||
// When a pool is not rewarded but the user has deposited to that pool, and the claim is synced;
|
||||
// Then the claim should be the same.
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: arbitraryCoins(),
|
||||
},
|
||||
RewardIndexes: nonEmptyMultiRewardIndexes,
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
poolID := "nonRewardPool"
|
||||
// No global indexes stored as this pool is not rewarded
|
||||
|
||||
userShares := i(1e9)
|
||||
|
||||
suite.keeper.SynchronizeSwapReward(suite.ctx, poolID, claim.Owner, userShares)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
suite.Equal(claim, syncedClaim)
|
||||
}
|
||||
|
||||
func (suite *SynchronizeSwapRewardTests) TestClaimUpdatedWhenNewRewardDenomAdded() {
|
||||
// When a new reward coin is added (via gov) to an already rewarded pool (that the user has already deposited to), and the claim is synced;
|
||||
// Then the user earns rewards for the time since the reward was added, and the new indexes are added.
|
||||
|
||||
originalReward := arbitraryCoins()
|
||||
poolID := "base/quote"
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: originalReward,
|
||||
},
|
||||
RewardIndexes: types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "reward",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
globalIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "reward",
|
||||
RewardFactor: d("2000.002"),
|
||||
},
|
||||
{
|
||||
CollateralType: "otherreward",
|
||||
// Indexes start at 0 when the reward is added by gov,
|
||||
// so this represents the syncing happening some time later.
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeGlobalSwapIndexes(globalIndexes)
|
||||
|
||||
userShares := i(1e9)
|
||||
|
||||
suite.keeper.SynchronizeSwapReward(suite.ctx, poolID, claim.Owner, userShares)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
// indexes should have the new reward denom added
|
||||
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
|
||||
// new reward is (new index - old index) * shares
|
||||
// The old index for `otherreward` isn't in the claim, so it's added starting at 0 for calculating the reward.
|
||||
suite.Equal(
|
||||
cs(c("reward", 1_000_001_000_000), c("otherreward", 1_000_001_000_000)).Add(originalReward...),
|
||||
syncedClaim.Reward,
|
||||
)
|
||||
}
|
||||
|
||||
func (suite *SynchronizeSwapRewardTests) TestClaimUpdatedWhenGlobalIndexesIncreasedAndSourceIsZero() {
|
||||
// Given some time has passed (meaning the global indexes have increased)
|
||||
// When the claim is synced, but the user has no shares
|
||||
// The user earns no rewards for the time passed, but the claim indexes are updated
|
||||
|
||||
poolID := "base/quote"
|
||||
|
||||
claim := types.SwapClaim{
|
||||
BaseMultiClaim: types.BaseMultiClaim{
|
||||
Owner: arbitraryAddress(),
|
||||
Reward: arbitraryCoins(),
|
||||
},
|
||||
RewardIndexes: types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("1000.001"),
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeSwapClaim(claim)
|
||||
|
||||
globalIndexes := types.MultiRewardIndexes{
|
||||
{
|
||||
CollateralType: poolID,
|
||||
RewardIndexes: types.RewardIndexes{
|
||||
{
|
||||
CollateralType: "rewarddenom",
|
||||
RewardFactor: d("2000.002"),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
suite.storeGlobalSwapIndexes(globalIndexes)
|
||||
|
||||
userShares := i(0)
|
||||
|
||||
suite.keeper.SynchronizeSwapReward(suite.ctx, poolID, claim.Owner, userShares)
|
||||
|
||||
syncedClaim, _ := suite.keeper.GetSwapClaim(suite.ctx, claim.Owner)
|
||||
// indexes updated from global
|
||||
suite.Equal(globalIndexes, syncedClaim.RewardIndexes)
|
||||
// reward is unchanged
|
||||
suite.Equal(claim.Reward, syncedClaim.Reward)
|
||||
}
|
@ -31,7 +31,7 @@ func TestAccumulateSwapRewards(t *testing.T) {
|
||||
}
|
||||
|
||||
func (suite *AccumulateSwapRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreased() {
|
||||
swapKeeper := &fakeSwapKeeper{d("1000000")}
|
||||
swapKeeper := &fakeSwapKeeper{i(1e6)}
|
||||
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper)
|
||||
|
||||
pool := "btc/usdx"
|
||||
@ -84,7 +84,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateUpdatedWhenBlockTimeHasIncreas
|
||||
}
|
||||
|
||||
func (suite *AccumulateSwapRewardsTests) TestLimitsOfAccumulationPrecision() {
|
||||
swapKeeper := &fakeSwapKeeper{d("100000000000000000")} // approximate shares in a $1B pool of 10^8 precision assets
|
||||
swapKeeper := &fakeSwapKeeper{i(1e17)} // approximate shares in a $1B pool of 10^8 precision ~$1 asset
|
||||
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper)
|
||||
|
||||
pool := "btc/usdx"
|
||||
@ -130,7 +130,7 @@ func (suite *AccumulateSwapRewardsTests) TestLimitsOfAccumulationPrecision() {
|
||||
}
|
||||
|
||||
func (suite *AccumulateSwapRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIncreased() {
|
||||
swapKeeper := &fakeSwapKeeper{d("1000000")}
|
||||
swapKeeper := &fakeSwapKeeper{i(1e6)}
|
||||
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper)
|
||||
|
||||
pool := "btc/usdx"
|
||||
@ -182,7 +182,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateUnchangedWhenBlockTimeHasNotIn
|
||||
}
|
||||
|
||||
func (suite *AccumulateSwapRewardsTests) TestStateAddedWhenStateDoesNotExist() {
|
||||
swapKeeper := &fakeSwapKeeper{d("1000000")}
|
||||
swapKeeper := &fakeSwapKeeper{i(1e6)}
|
||||
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper)
|
||||
|
||||
pool := "btc/usdx"
|
||||
@ -225,7 +225,7 @@ func (suite *AccumulateSwapRewardsTests) TestStateAddedWhenStateDoesNotExist() {
|
||||
suite.checkStoredIndexesEqual(pool, expectedIndexes)
|
||||
}
|
||||
func (suite *AccumulateSwapRewardsTests) TestNoPanicWhenStateDoesNotExist() {
|
||||
swapKeeper := &fakeSwapKeeper{d("0")}
|
||||
swapKeeper := &fakeSwapKeeper{i(0)}
|
||||
suite.keeper = suite.NewKeeper(&fakeParamSubspace{}, nil, nil, nil, nil, nil, swapKeeper)
|
||||
|
||||
pool := "btc/usdx"
|
||||
@ -252,12 +252,16 @@ func (suite *AccumulateSwapRewardsTests) TestNoPanicWhenStateDoesNotExist() {
|
||||
}
|
||||
|
||||
type fakeSwapKeeper struct {
|
||||
poolShares sdk.Dec
|
||||
poolShares sdk.Int
|
||||
}
|
||||
|
||||
func (k fakeSwapKeeper) GetPoolShares(ctx sdk.Context, poolID string) (sdk.Dec, bool) {
|
||||
func (k fakeSwapKeeper) GetPoolShares(ctx sdk.Context, poolID string) (sdk.Int, bool) {
|
||||
return k.poolShares, true
|
||||
}
|
||||
func (k fakeSwapKeeper) GetDepositorSharesInPool(ctx sdk.Context, depositor sdk.AccAddress, poolID string) (sdk.Int, bool) {
|
||||
// This is just to implement the swap keeper interface.
|
||||
return sdk.Int{}, false
|
||||
}
|
||||
|
||||
// note: amino panics when encoding times ≥ the start of year 10000.
|
||||
var distantFuture = time.Date(9000, 1, 1, 0, 0, 0, 0, time.UTC)
|
||||
|
@ -87,10 +87,12 @@ func (suite *unitTester) storeGlobalSwapIndexes(indexes types.MultiRewardIndexes
|
||||
func (suite *unitTester) storeHardClaim(claim types.HardLiquidityProviderClaim) {
|
||||
suite.keeper.SetHardLiquidityProviderClaim(suite.ctx, claim)
|
||||
}
|
||||
|
||||
func (suite *unitTester) storeDelegatorClaim(claim types.DelegatorClaim) {
|
||||
suite.keeper.SetDelegatorClaim(suite.ctx, claim)
|
||||
}
|
||||
func (suite *unitTester) storeSwapClaim(claim types.SwapClaim) {
|
||||
suite.keeper.SetSwapClaim(suite.ctx, claim)
|
||||
}
|
||||
|
||||
type fakeParamSubspace struct {
|
||||
params types.Params
|
||||
|
@ -12,6 +12,7 @@ const (
|
||||
USDXMintingClaimType = "usdx_minting"
|
||||
HardLiquidityProviderClaimType = "hard_liquidity_provider"
|
||||
DelegatorClaimType = "delegator_claim"
|
||||
SwapClaimType = "swap"
|
||||
BondDenom = "ukava"
|
||||
)
|
||||
|
||||
@ -314,6 +315,71 @@ func (cs DelegatorClaims) Validate() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// SwapClaim stores the swap rewards that can be claimed by owner
|
||||
type SwapClaim struct {
|
||||
BaseMultiClaim `json:"base_claim" yaml:"base_claim"`
|
||||
RewardIndexes MultiRewardIndexes `json:"reward_indexes" yaml:"reward_indexes"`
|
||||
}
|
||||
|
||||
// NewSwapClaim returns a new SwapClaim
|
||||
func NewSwapClaim(owner sdk.AccAddress, rewards sdk.Coins, rewardIndexes MultiRewardIndexes) SwapClaim {
|
||||
return SwapClaim{
|
||||
BaseMultiClaim: BaseMultiClaim{
|
||||
Owner: owner,
|
||||
Reward: rewards,
|
||||
},
|
||||
RewardIndexes: rewardIndexes,
|
||||
}
|
||||
}
|
||||
|
||||
// GetType returns the claim's type
|
||||
func (c SwapClaim) GetType() string { return SwapClaimType }
|
||||
|
||||
// GetReward returns the claim's reward coin
|
||||
func (c SwapClaim) GetReward() sdk.Coins { return c.Reward }
|
||||
|
||||
// GetOwner returns the claim's owner
|
||||
func (c SwapClaim) GetOwner() sdk.AccAddress { return c.Owner }
|
||||
|
||||
// Validate performs a basic check of a SwapClaim fields
|
||||
func (c SwapClaim) Validate() error {
|
||||
if err := c.RewardIndexes.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
return c.BaseMultiClaim.Validate()
|
||||
}
|
||||
|
||||
// String implements fmt.Stringer
|
||||
func (c SwapClaim) String() string {
|
||||
return fmt.Sprintf(`%s
|
||||
Reward Indexes: %s,
|
||||
`, c.BaseMultiClaim, c.RewardIndexes)
|
||||
}
|
||||
|
||||
// HasRewardIndex check if a claim has a reward index for the input pool ID.
|
||||
func (c SwapClaim) HasRewardIndex(poolID string) (int64, bool) {
|
||||
for index, ri := range c.RewardIndexes {
|
||||
if ri.CollateralType == poolID {
|
||||
return int64(index), true
|
||||
}
|
||||
}
|
||||
return 0, false
|
||||
}
|
||||
|
||||
// SwapClaims slice of SwapClaim
|
||||
type SwapClaims []SwapClaim
|
||||
|
||||
// Validate checks if all the claims are valid.
|
||||
func (cs SwapClaims) Validate() error {
|
||||
for _, c := range cs {
|
||||
if err := c.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ---------------------- Reward indexes are used internally in the store ----------------------
|
||||
|
||||
// RewardIndex stores reward accumulation information
|
||||
|
@ -18,67 +18,125 @@ func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amo
|
||||
// c is a helper function for created sdk.Coins types in tests
|
||||
func cs(coins ...sdk.Coin) sdk.Coins { return sdk.NewCoins(coins...) }
|
||||
|
||||
func TestClaimsValidate(t *testing.T) {
|
||||
func TestClaims_Validate(t *testing.T) {
|
||||
owner := sdk.AccAddress(crypto.AddressHash([]byte("KavaTestUser1")))
|
||||
|
||||
testCases := []struct {
|
||||
msg string
|
||||
claims USDXMintingClaims
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"valid",
|
||||
USDXMintingClaims{
|
||||
NewUSDXMintingClaim(owner, sdk.NewCoin("bnb", sdk.OneInt()), RewardIndexes{NewRewardIndex("bnb-a", sdk.ZeroDec())}),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid owner",
|
||||
USDXMintingClaims{
|
||||
USDXMintingClaim{
|
||||
BaseClaim: BaseClaim{
|
||||
Owner: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid reward",
|
||||
USDXMintingClaims{
|
||||
{
|
||||
BaseClaim: BaseClaim{
|
||||
Owner: owner,
|
||||
Reward: sdk.Coin{Denom: "", Amount: sdk.ZeroInt()},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid collateral type",
|
||||
USDXMintingClaims{
|
||||
{
|
||||
BaseClaim: BaseClaim{
|
||||
Owner: owner,
|
||||
Reward: sdk.NewCoin("bnb", sdk.OneInt()),
|
||||
},
|
||||
RewardIndexes: []RewardIndex{{"", sdk.ZeroDec()}},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
t.Run("USDXMintingClaims", func(t *testing.T) {
|
||||
|
||||
for _, tc := range testCases {
|
||||
err := tc.claims.Validate()
|
||||
if tc.expPass {
|
||||
require.NoError(t, err, tc.msg)
|
||||
} else {
|
||||
require.Error(t, err, tc.msg)
|
||||
testCases := []struct {
|
||||
name string
|
||||
claims USDXMintingClaims
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
"valid",
|
||||
USDXMintingClaims{
|
||||
NewUSDXMintingClaim(owner, sdk.NewCoin("bnb", sdk.OneInt()), RewardIndexes{NewRewardIndex("bnb-a", sdk.ZeroDec())}),
|
||||
},
|
||||
true,
|
||||
},
|
||||
{
|
||||
"invalid owner",
|
||||
USDXMintingClaims{
|
||||
USDXMintingClaim{
|
||||
BaseClaim: BaseClaim{
|
||||
Owner: nil,
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid reward",
|
||||
USDXMintingClaims{
|
||||
{
|
||||
BaseClaim: BaseClaim{
|
||||
Owner: owner,
|
||||
Reward: sdk.Coin{Denom: "", Amount: sdk.ZeroInt()},
|
||||
},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
{
|
||||
"invalid collateral type",
|
||||
USDXMintingClaims{
|
||||
{
|
||||
BaseClaim: BaseClaim{
|
||||
Owner: owner,
|
||||
Reward: sdk.NewCoin("bnb", sdk.OneInt()),
|
||||
},
|
||||
RewardIndexes: []RewardIndex{{"", sdk.ZeroDec()}},
|
||||
},
|
||||
},
|
||||
false,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := tc.claims.Validate()
|
||||
if tc.expPass {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
t.Run("SwapClaims", func(t *testing.T) {
|
||||
|
||||
validRewardIndexes := RewardIndexes{}.With("swap", d("0.002"))
|
||||
validMultiRewardIndexes := MultiRewardIndexes{}.With("btcb/usdx", validRewardIndexes)
|
||||
invalidRewardIndexes := RewardIndexes{}.With("swap", d("-0.002"))
|
||||
invalidMultiRewardIndexes := MultiRewardIndexes{}.With("btcb/usdx", invalidRewardIndexes)
|
||||
|
||||
testCases := []struct {
|
||||
name string
|
||||
claims SwapClaims
|
||||
expPass bool
|
||||
}{
|
||||
{
|
||||
name: "valid",
|
||||
claims: SwapClaims{
|
||||
NewSwapClaim(owner, cs(c("bnb", 1)), validMultiRewardIndexes),
|
||||
},
|
||||
expPass: true,
|
||||
},
|
||||
{
|
||||
name: "invalid owner",
|
||||
claims: SwapClaims{
|
||||
NewSwapClaim(nil, cs(c("bnb", 1)), validMultiRewardIndexes),
|
||||
},
|
||||
expPass: false,
|
||||
},
|
||||
{
|
||||
name: "invalid reward",
|
||||
claims: SwapClaims{
|
||||
NewSwapClaim(owner, sdk.Coins{sdk.Coin{Denom: "invalid😫"}}, validMultiRewardIndexes),
|
||||
},
|
||||
expPass: false,
|
||||
},
|
||||
{
|
||||
name: "invalid indexes",
|
||||
claims: SwapClaims{
|
||||
NewSwapClaim(nil, cs(c("bnb", 1)), invalidMultiRewardIndexes),
|
||||
},
|
||||
expPass: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
err := tc.claims.Validate()
|
||||
if tc.expPass {
|
||||
require.NoError(t, err)
|
||||
} else {
|
||||
require.Error(t, err)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestRewardIndexes(t *testing.T) {
|
||||
|
@ -53,7 +53,8 @@ type HardKeeper interface {
|
||||
|
||||
// SwapKeeper defines the required methods needed by this modules keeper
|
||||
type SwapKeeper interface {
|
||||
GetPoolShares(ctx sdk.Context, poolID string) (shares sdk.Dec, found bool)
|
||||
GetPoolShares(ctx sdk.Context, poolID string) (shares sdk.Int, found bool)
|
||||
GetDepositorSharesInPool(ctx sdk.Context, depositor sdk.AccAddress, poolID string) (shares sdk.Int, found bool)
|
||||
}
|
||||
|
||||
// AccountKeeper defines the expected keeper interface for interacting with account
|
||||
|
@ -17,11 +17,12 @@ type GenesisState struct {
|
||||
USDXMintingClaims USDXMintingClaims `json:"usdx_minting_claims" yaml:"usdx_minting_claims"`
|
||||
HardLiquidityProviderClaims HardLiquidityProviderClaims `json:"hard_liquidity_provider_claims" yaml:"hard_liquidity_provider_claims"`
|
||||
DelegatorClaims DelegatorClaims `json:"delegator_claims" yaml:"delegator_claims"`
|
||||
SwapClaims SwapClaims `json:"swap_claims" yaml:"swap_claims"`
|
||||
}
|
||||
|
||||
// NewGenesisState returns a new genesis state
|
||||
func NewGenesisState(params Params, usdxAccumTimes, hardSupplyAccumTimes, hardBorrowAccumTimes, delegatorAccumTimes,
|
||||
swapAccumTimes GenesisAccumulationTimes, c USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims) GenesisState {
|
||||
swapAccumTimes GenesisAccumulationTimes, c USDXMintingClaims, hc HardLiquidityProviderClaims, dc DelegatorClaims, sc SwapClaims) GenesisState {
|
||||
return GenesisState{
|
||||
Params: params,
|
||||
USDXAccumulationTimes: usdxAccumTimes,
|
||||
@ -32,6 +33,7 @@ func NewGenesisState(params Params, usdxAccumTimes, hardSupplyAccumTimes, hardBo
|
||||
USDXMintingClaims: c,
|
||||
HardLiquidityProviderClaims: hc,
|
||||
DelegatorClaims: dc,
|
||||
SwapClaims: sc,
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,6 +49,7 @@ func DefaultGenesisState() GenesisState {
|
||||
USDXMintingClaims: DefaultUSDXClaims,
|
||||
HardLiquidityProviderClaims: DefaultHardClaims,
|
||||
DelegatorClaims: DefaultDelegatorClaims,
|
||||
SwapClaims: DefaultSwapClaims,
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,13 +75,16 @@ func (gs GenesisState) Validate() error {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := gs.HardLiquidityProviderClaims.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gs.USDXMintingClaims.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
return gs.DelegatorClaims.Validate()
|
||||
if err := gs.HardLiquidityProviderClaims.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := gs.DelegatorClaims.Validate(); err != nil {
|
||||
return err
|
||||
}
|
||||
return gs.SwapClaims.Validate()
|
||||
}
|
||||
|
||||
// Equal checks whether two gov GenesisState structs are equivalent
|
||||
|
@ -141,6 +141,7 @@ func TestGenesisStateValidate(t *testing.T) {
|
||||
tc.args.claims,
|
||||
DefaultHardClaims,
|
||||
DefaultDelegatorClaims,
|
||||
DefaultSwapClaims,
|
||||
)
|
||||
err := gs.Validate()
|
||||
if tc.errArgs.expectPass {
|
||||
|
@ -34,8 +34,9 @@ var (
|
||||
DelegatorClaimKeyPrefix = []byte{0x09} // prefix for keys that store delegator claims
|
||||
DelegatorRewardIndexesKeyPrefix = []byte{0x10} // prefix for key that stores delegator reward indexes
|
||||
PreviousDelegatorRewardAccrualTimeKeyPrefix = []byte{0x11} // prefix for key that stores the previous time delegator rewards accrued
|
||||
SwapRewardIndexesKeyPrefix = []byte{0x12} // prefix for key that stores swap reward indexes
|
||||
PreviousSwapRewardAccrualTimeKeyPrefix = []byte{0x13} // prefix for key that stores the previous time swap rewards accrued
|
||||
SwapClaimKeyPrefix = []byte{0x12} // prefix for keys that store swap claims
|
||||
SwapRewardIndexesKeyPrefix = []byte{0x13} // prefix for key that stores swap reward indexes
|
||||
PreviousSwapRewardAccrualTimeKeyPrefix = []byte{0x14} // prefix for key that stores the previous time swap rewards accrued
|
||||
|
||||
USDXMintingRewardDenom = "ukava"
|
||||
HardLiquidityRewardDenom = "hard"
|
||||
|
@ -38,6 +38,7 @@ var (
|
||||
DefaultUSDXClaims = USDXMintingClaims{}
|
||||
DefaultHardClaims = HardLiquidityProviderClaims{}
|
||||
DefaultDelegatorClaims = DelegatorClaims{}
|
||||
DefaultSwapClaims = SwapClaims{}
|
||||
DefaultGenesisAccumulationTimes = GenesisAccumulationTimes{}
|
||||
DefaultClaimEnd = tmtime.Canonical(time.Unix(1, 0))
|
||||
GovDenom = cdptypes.DefaultGovDenom
|
||||
|
@ -6,169 +6,54 @@ import (
|
||||
|
||||
// Querier routes for the incentive module
|
||||
const (
|
||||
QueryGetRewards = "rewards"
|
||||
QueryGetHardRewards = "hard-rewards"
|
||||
QueryGetHardRewardsUnsynced = "hard-rewards-unsynced"
|
||||
QueryGetUSDXMintingRewards = "usdx-minting-rewards"
|
||||
QueryGetUSDXMintingRewardsUnsynced = "usdx-minting-rewards-unsynced"
|
||||
QueryGetDelegatorRewards = "delegator-rewards"
|
||||
QueryGetDelegatorRewardsUnsynced = "delegator-rewards-unsynced"
|
||||
QueryGetRewardFactors = "reward-factors"
|
||||
QueryGetParams = "parameters"
|
||||
QueryGetRewardPeriods = "reward-periods"
|
||||
QueryGetClaimPeriods = "claim-periods"
|
||||
RestClaimCollateralType = "collateral_type"
|
||||
RestClaimOwner = "owner"
|
||||
RestClaimType = "type"
|
||||
RestUnsynced = "unsynced"
|
||||
QueryGetHardRewards = "hard-rewards"
|
||||
QueryGetUSDXMintingRewards = "usdx-minting-rewards"
|
||||
QueryGetDelegatorRewards = "delegator-rewards"
|
||||
QueryGetSwapRewards = "swap-rewards"
|
||||
QueryGetRewardFactors = "reward-factors"
|
||||
QueryGetParams = "parameters"
|
||||
|
||||
RestClaimCollateralType = "collateral_type"
|
||||
RestClaimOwner = "owner"
|
||||
RestClaimType = "type"
|
||||
RestUnsynced = "unsynced"
|
||||
)
|
||||
|
||||
// QueryRewardsParams params for query /incentive/rewards
|
||||
// QueryRewardsParams params for query /incentive/rewards/<claim type>
|
||||
type QueryRewardsParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
Type string
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress `json:"owner" yaml:"owner"`
|
||||
Unsynchronized bool `json:"unsynchronized" yaml:"unsynchronized"`
|
||||
}
|
||||
|
||||
// NewQueryRewardsParams returns QueryRewardsParams
|
||||
func NewQueryRewardsParams(page, limit int, owner sdk.AccAddress, rewardType string) QueryRewardsParams {
|
||||
func NewQueryRewardsParams(page, limit int, owner sdk.AccAddress, unsynchronized bool) QueryRewardsParams {
|
||||
return QueryRewardsParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
Type: rewardType,
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
Unsynchronized: unsynchronized,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryUSDXMintingRewardsParams params for query /incentive/rewards type usdx-minting
|
||||
type QueryUSDXMintingRewardsParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
// QueryGetRewardFactorsResponse holds the response to a reward factor query
|
||||
type QueryGetRewardFactorsResponse struct {
|
||||
USDXMintingRewardFactors RewardIndexes `json:"usdx_minting_reward_factors" yaml:"usdx_minting_reward_factors"`
|
||||
HardSupplyRewardFactors MultiRewardIndexes `json:"hard_supply_reward_factors" yaml:"hard_supply_reward_factors"`
|
||||
HardBorrowRewardFactors MultiRewardIndexes `json:"hard_borrow_reward_factors" yaml:"hard_borrow_reward_factors"`
|
||||
DelegatorRewardFactors MultiRewardIndexes `json:"delegator_reward_factors" yaml:"delegator_reward_factors"`
|
||||
SwapRewardFactors MultiRewardIndexes `json:"swap_reward_factors" yaml:"swap_reward_factors"`
|
||||
}
|
||||
|
||||
// NewQueryUSDXMintingRewardsParams returns QueryUSDXMintingRewardsParams
|
||||
func NewQueryUSDXMintingRewardsParams(page, limit int, owner sdk.AccAddress) QueryUSDXMintingRewardsParams {
|
||||
return QueryUSDXMintingRewardsParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
// NewQueryGetRewardFactorsResponse returns a new instance of QueryAllRewardFactorsResponse
|
||||
func NewQueryGetRewardFactorsResponse(usdxMintingFactors RewardIndexes, supplyFactors,
|
||||
hardBorrowFactors, delegatorFactors, swapFactors MultiRewardIndexes) QueryGetRewardFactorsResponse {
|
||||
return QueryGetRewardFactorsResponse{
|
||||
USDXMintingRewardFactors: usdxMintingFactors,
|
||||
HardSupplyRewardFactors: supplyFactors,
|
||||
HardBorrowRewardFactors: hardBorrowFactors,
|
||||
DelegatorRewardFactors: delegatorFactors,
|
||||
SwapRewardFactors: swapFactors,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryUSDXMintingRewardsUnsyncedParams params for query unsynced /incentive/rewards type usdx-minting
|
||||
type QueryUSDXMintingRewardsUnsyncedParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryUSDXMintingRewardsUnsyncedParams returns QueryUSDXMintingRewardsUnsyncedParams
|
||||
func NewQueryUSDXMintingRewardsUnsyncedParams(page, limit int, owner sdk.AccAddress) QueryUSDXMintingRewardsUnsyncedParams {
|
||||
return QueryUSDXMintingRewardsUnsyncedParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryHardRewardsParams params for query /incentive/rewards type hard
|
||||
type QueryHardRewardsParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryHardRewardsParams returns QueryHardRewardsParams
|
||||
func NewQueryHardRewardsParams(page, limit int, owner sdk.AccAddress) QueryHardRewardsParams {
|
||||
return QueryHardRewardsParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryHardRewardsUnsyncedParams params for query unsynced /incentive/rewards type hard
|
||||
type QueryHardRewardsUnsyncedParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryHardRewardsUnsyncedParams returns QueryHardRewardsUnsyncedParams
|
||||
func NewQueryHardRewardsUnsyncedParams(page, limit int, owner sdk.AccAddress) QueryHardRewardsUnsyncedParams {
|
||||
return QueryHardRewardsUnsyncedParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryRewardFactorsParams is the params for a filtered reward factors query
|
||||
type QueryRewardFactorsParams struct {
|
||||
Denom string `json:"denom" yaml:"denom"`
|
||||
}
|
||||
|
||||
// NewQueryRewardFactorsParams creates a new QueryRewardFactorsParams
|
||||
func NewQueryRewardFactorsParams(denom string) QueryRewardFactorsParams {
|
||||
return QueryRewardFactorsParams{
|
||||
Denom: denom,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryDelegatorRewardsParams params for query /incentive/rewards type delegator
|
||||
type QueryDelegatorRewardsParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryDelegatorRewardsParams returns QueryDelegatorRewardsParams
|
||||
func NewQueryDelegatorRewardsParams(page, limit int, owner sdk.AccAddress) QueryDelegatorRewardsParams {
|
||||
return QueryDelegatorRewardsParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
}
|
||||
}
|
||||
|
||||
// QueryDelegatorRewardsUnsyncedParams params for query unsynced /incentive/rewards type delegator
|
||||
type QueryDelegatorRewardsUnsyncedParams struct {
|
||||
Page int `json:"page" yaml:"page"`
|
||||
Limit int `json:"limit" yaml:"limit"`
|
||||
Owner sdk.AccAddress
|
||||
}
|
||||
|
||||
// NewQueryDelegatorRewardsUnsyncedParams returns QueryDelegatorRewardsUnsyncedParams
|
||||
func NewQueryDelegatorRewardsUnsyncedParams(page, limit int, owner sdk.AccAddress) QueryDelegatorRewardsUnsyncedParams {
|
||||
return QueryDelegatorRewardsUnsyncedParams{
|
||||
Page: page,
|
||||
Limit: limit,
|
||||
Owner: owner,
|
||||
}
|
||||
}
|
||||
|
||||
// RewardFactor is a unique type returned by reward factor queries
|
||||
type RewardFactor struct {
|
||||
Denom string `json:"denom" yaml:"denom"`
|
||||
USDXMintingRewardFactor sdk.Dec `json:"usdx_minting_reward_factor" yaml:"usdx_minting_reward_factor"`
|
||||
HardSupplyRewardFactors RewardIndexes `json:"hard_supply_reward_factors" yaml:"hard_supply_reward_factors"`
|
||||
HardBorrowRewardFactors RewardIndexes `json:"hard_borrow_reward_factors" yaml:"hard_borrow_reward_factors"`
|
||||
DelegatorRewardFactors RewardIndexes `json:"delegator_reward_factors" yaml:"delegator_reward_factors"`
|
||||
}
|
||||
|
||||
// NewRewardFactor returns a new instance of RewardFactor
|
||||
func NewRewardFactor(denom string, usdxMintingRewardFactor sdk.Dec, hardSupplyRewardFactors,
|
||||
hardBorrowRewardFactors, delegatorRewardFactors RewardIndexes) RewardFactor {
|
||||
return RewardFactor{
|
||||
Denom: denom,
|
||||
USDXMintingRewardFactor: usdxMintingRewardFactor,
|
||||
HardSupplyRewardFactors: hardSupplyRewardFactors,
|
||||
HardBorrowRewardFactors: hardBorrowRewardFactors,
|
||||
DelegatorRewardFactors: delegatorRewardFactors,
|
||||
}
|
||||
}
|
||||
|
||||
// RewardFactors is a slice of RewardFactor
|
||||
type RewardFactors = []RewardFactor
|
||||
|
@ -2,9 +2,35 @@ package keeper
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
|
||||
"github.com/kava-labs/kava/x/swap/types"
|
||||
)
|
||||
|
||||
func (k Keeper) GetPoolShares(ctx sdk.Context, poolID string) (sdk.Dec, bool) {
|
||||
func (k Keeper) GetPoolShares(ctx sdk.Context, poolID string) (sdk.Int, bool) {
|
||||
// FIXME return pool shares once merged with acceptance branch
|
||||
return sdk.Dec{}, false
|
||||
return sdk.Int{}, false
|
||||
}
|
||||
|
||||
func (k *Keeper) GetDepositorSharesInPool(ctx sdk.Context, depositor sdk.AccAddress, poolID string) (sdk.Int, bool) {
|
||||
// FIXME return depositor shares once merged with acceptance branch
|
||||
return sdk.Int{}, false
|
||||
}
|
||||
|
||||
// Implements SwapHooks interface
|
||||
var _ types.SwapHooks = Keeper{}
|
||||
|
||||
// FIXME call hooks within pool logic
|
||||
|
||||
// AfterPoolDepositCreated - call hook if registered
|
||||
func (k Keeper) AfterPoolDepositCreated(ctx sdk.Context, poolID string, depositor sdk.AccAddress, sharesOwned sdk.Int) {
|
||||
if k.hooks != nil {
|
||||
k.hooks.AfterPoolDepositCreated(ctx, poolID, depositor, sharesOwned)
|
||||
}
|
||||
}
|
||||
|
||||
// BeforePoolDepositModified - call hook if registered
|
||||
func (k Keeper) BeforePoolDepositModified(ctx sdk.Context, poolID string, depositor sdk.AccAddress, sharesOwned sdk.Int) {
|
||||
if k.hooks != nil {
|
||||
k.hooks.BeforePoolDepositModified(ctx, poolID, depositor, sharesOwned)
|
||||
}
|
||||
}
|
||||
|
@ -14,6 +14,7 @@ type Keeper struct {
|
||||
key sdk.StoreKey
|
||||
cdc *codec.Codec
|
||||
paramSubspace subspace.Subspace
|
||||
hooks types.SwapHooks
|
||||
accountKeeper types.AccountKeeper
|
||||
supplyKeeper types.SupplyKeeper
|
||||
}
|
||||
@ -39,6 +40,15 @@ func NewKeeper(
|
||||
}
|
||||
}
|
||||
|
||||
// SetHooks adds hooks to the keeper.
|
||||
func (k *Keeper) SetHooks(sh types.SwapHooks) *Keeper {
|
||||
if k.hooks != nil {
|
||||
panic("cannot set swap hooks twice")
|
||||
}
|
||||
k.hooks = sh
|
||||
return k
|
||||
}
|
||||
|
||||
// GetParams returns the params from the store
|
||||
func (k Keeper) GetParams(ctx sdk.Context) types.Params {
|
||||
var p types.Params
|
||||
|
@ -1,4 +1,4 @@
|
||||
package types // noalias
|
||||
package types
|
||||
|
||||
import (
|
||||
sdk "github.com/cosmos/cosmos-sdk/types"
|
||||
@ -20,3 +20,9 @@ type AccountKeeper interface {
|
||||
GetAccount(ctx sdk.Context, addr sdk.AccAddress) authexported.Account
|
||||
SetAccount(ctx sdk.Context, acc authexported.Account)
|
||||
}
|
||||
|
||||
// SwapHooks are event hooks called when a user's deposit to a swap pool changes.
|
||||
type SwapHooks interface {
|
||||
AfterPoolDepositCreated(ctx sdk.Context, poolID string, depositor sdk.AccAddress, sharedOwned sdk.Int)
|
||||
BeforePoolDepositModified(ctx sdk.Context, poolID string, depositor sdk.AccAddress, sharedOwned sdk.Int)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user