mirror of
https://github.com/0glabs/0g-chain.git
synced 2024-12-27 00:35:18 +00:00
614d4e40fe
* Update cometbft, cosmos, ethermint, and ibc-go * Replace github.com/tendermint/tendermint by github.com/cometbft/cometbft * Replace github.com/tendermint/tm-db by github.com/cometbft/cometbft-db * Replace gogo/protobuf with cosmos/gogoproto & simapp replacement * Replace cosmos-sdk/simapp/helpers with cosmos-sdk/testutil/sims * Remove no longer used simulations * Replace ibchost with ibcexported See https://github.com/cosmos/ibc-go/blob/v7.2.2/docs/migrations/v6-to-v7.md#ibc-module-constants * Add new consensus params keeper * Add consensus keeper to blockers * Fix keeper and module issues in app.go * Add IsSendEnabledCoins and update SetParams interface changes * Fix protobuf build for cosmos 47 (#1800) * fix cp errors by using -f; fix lint by only linting our proto dir; and use proofs.proto directly from ics23 for ibc-go v7 * run proto-all; commit updated third party deps and swagger changes * regenerate proto files * use correct gocosmos build plugin for buf * re-gen all protobuf files to update paths for new gocosmos plugin * update protoc and buf to latest versions * fix staking keeper issues in app.go * update tally handler for gov changes * chain id fix and flag fixes * update deps for cometbft 47.7 upgrade * remove all module legacy queriers * update stakingKeeper to pointer * Replace ModuleCdc from govv1beta1 to govcodec * remove simulations * abci.LastCommitInfo → abci.CommitInfo * Remove unused code in keys.go * simapp.MakeTestEncodingConfig -> moduletestutil.MakeTestEncodingConfi * Fix chain id issues in tests * Fix remaining unit test issues * Update changelog for upgrade * Fix e2e tests using updated kvtool * Update protonet to v47 compatible genesis * Bump cometbft-db to v0.9.1-kava.1 * Update kvtool * Remove extra changelog * Fix merged rocksdb issues * go mod cleanup * Bump cometbft-db to v9 and go to 1.21 * Bump rocksdb version to v8.10.0 * Update kvtool to latest version * Update gin to v1.9.0 * Use ibctm.ModuleName in app_test * Fallback to genesis chain id instead of client toml * Remove all simulations * Fix cdp migrations issue with v47 * Update dependencies to correct tags --------- Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com>
511 lines
19 KiB
Go
511 lines
19 KiB
Go
package keeper_test
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
tmproto "github.com/cometbft/cometbft/proto/tendermint/types"
|
|
sdk "github.com/cosmos/cosmos-sdk/types"
|
|
proposaltypes "github.com/cosmos/cosmos-sdk/x/params/types/proposal"
|
|
"github.com/stretchr/testify/suite"
|
|
|
|
"github.com/kava-labs/kava/app"
|
|
cdpkeeper "github.com/kava-labs/kava/x/cdp/keeper"
|
|
cdptypes "github.com/kava-labs/kava/x/cdp/types"
|
|
"github.com/kava-labs/kava/x/incentive/keeper"
|
|
"github.com/kava-labs/kava/x/incentive/testutil"
|
|
"github.com/kava-labs/kava/x/incentive/types"
|
|
kavadisttypes "github.com/kava-labs/kava/x/kavadist/types"
|
|
)
|
|
|
|
type USDXIntegrationTests struct {
|
|
testutil.IntegrationTester
|
|
|
|
genesisTime time.Time
|
|
addrs []sdk.AccAddress
|
|
}
|
|
|
|
func TestUSDXIntegration(t *testing.T) {
|
|
suite.Run(t, new(USDXIntegrationTests))
|
|
}
|
|
|
|
// SetupTest is run automatically before each suite test
|
|
func (suite *USDXIntegrationTests) SetupTest() {
|
|
_, suite.addrs = app.GeneratePrivKeyAddressPairs(5)
|
|
|
|
suite.genesisTime = time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC)
|
|
}
|
|
|
|
func (suite *USDXIntegrationTests) ProposeAndVoteOnNewRewardPeriods(committeeID uint64, voter sdk.AccAddress, newPeriods types.RewardPeriods) {
|
|
suite.ProposeAndVoteOnNewParams(
|
|
voter,
|
|
committeeID,
|
|
[]proposaltypes.ParamChange{{
|
|
Subspace: types.ModuleName,
|
|
Key: string(types.KeyUSDXMintingRewardPeriods),
|
|
Value: string(types.ModuleCdc.LegacyAmino.MustMarshalJSON(newPeriods)),
|
|
}})
|
|
}
|
|
|
|
func (suite *USDXIntegrationTests) TestSingleUserAccumulatesRewardsAfterSyncing() {
|
|
userA := suite.addrs[0]
|
|
|
|
authBulder := app.NewAuthBankGenesisBuilder().
|
|
WithSimpleModuleAccount(kavadisttypes.ModuleName, cs(c(types.USDXMintingRewardDenom, 1e18))). // Fill kavadist with enough coins to pay out any reward
|
|
WithSimpleAccount(userA, cs(c("bnb", 1e12))) // give the user some coins
|
|
|
|
incentBuilder := testutil.NewIncentiveGenesisBuilder().
|
|
WithGenesisTime(suite.genesisTime).
|
|
WithMultipliers(types.MultipliersPerDenoms{{
|
|
Denom: types.USDXMintingRewardDenom,
|
|
Multipliers: types.Multipliers{types.NewMultiplier("large", 12, d("1.0"))}, // keep payout at 1.0 to make maths easier
|
|
}}).
|
|
WithSimpleUSDXRewardPeriod("bnb-a", c(types.USDXMintingRewardDenom, 1e6))
|
|
|
|
suite.SetApp()
|
|
suite.WithGenesisTime(suite.genesisTime)
|
|
suite.StartChain(
|
|
NewPricefeedGenStateMultiFromTime(suite.App.AppCodec(), suite.genesisTime),
|
|
NewCDPGenStateMulti(suite.App.AppCodec()),
|
|
authBulder.BuildMarshalled(suite.App.AppCodec()),
|
|
incentBuilder.BuildMarshalled(suite.App.AppCodec()),
|
|
)
|
|
|
|
// User creates a CDP to begin earning rewards.
|
|
suite.NoError(
|
|
suite.DeliverMsgCreateCDP(userA, c("bnb", 1e10), c(cdptypes.DefaultStableDenom, 1e9), "bnb-a"),
|
|
)
|
|
|
|
// Let time pass to accumulate interest on the deposit
|
|
// Use one long block instead of many to reduce any rounding errors, and speed up tests.
|
|
suite.NextBlockAfter(1e6 * time.Second) // about 12 days
|
|
|
|
// User repays and borrows just to sync their CDP
|
|
suite.NoError(
|
|
suite.DeliverCDPMsgRepay(userA, "bnb-a", c(cdptypes.DefaultStableDenom, 1)),
|
|
)
|
|
suite.NoError(
|
|
suite.DeliverCDPMsgBorrow(userA, "bnb-a", c(cdptypes.DefaultStableDenom, 1)),
|
|
)
|
|
|
|
// Accumulate more rewards.
|
|
// The user still has the same percentage of all CDP debt (100%) so their rewards should be the same as in the previous block.
|
|
suite.NextBlockAfter(1e6 * time.Second) // about 12 days
|
|
|
|
// User claims all their rewards
|
|
msg := types.NewMsgClaimUSDXMintingReward(userA.String(), "large")
|
|
suite.Require().NoError(suite.DeliverIncentiveMsg(&msg))
|
|
|
|
// The users has always had 100% of cdp debt, so they should receive all rewards for the previous two blocks.
|
|
// Total rewards for each block is block duration * rewards per second
|
|
accuracy := 1e-18 // using a very high accuracy to flag future small calculation changes
|
|
suite.BalanceInEpsilon(userA, cs(c("bnb", 1e12-1e10), c(cdptypes.DefaultStableDenom, 1e9), c(types.USDXMintingRewardDenom, 2*1e6*1e6)), accuracy)
|
|
}
|
|
|
|
func (suite *USDXIntegrationTests) TestSingleUserAccumulatesRewardsWithoutSyncing() {
|
|
user := suite.addrs[0]
|
|
initialCollateral := c("bnb", 1e9)
|
|
|
|
authBuilder := app.NewAuthBankGenesisBuilder().
|
|
WithSimpleModuleAccount(kavadisttypes.ModuleName, cs(c(types.USDXMintingRewardDenom, 1e18))). // Fill kavadist with enough coins to pay out any reward
|
|
WithSimpleAccount(user, cs(initialCollateral))
|
|
|
|
collateralType := "bnb-a"
|
|
|
|
incentBuilder := testutil.NewIncentiveGenesisBuilder().
|
|
WithGenesisTime(suite.genesisTime).
|
|
WithMultipliers(types.MultipliersPerDenoms{{
|
|
Denom: types.USDXMintingRewardDenom,
|
|
Multipliers: types.Multipliers{types.NewMultiplier("large", 12, d("1.0"))}, // keep payout at 1.0 to make maths easier
|
|
}}).
|
|
WithSimpleUSDXRewardPeriod(collateralType, c(types.USDXMintingRewardDenom, 1e6))
|
|
|
|
suite.SetApp()
|
|
suite.WithGenesisTime(suite.genesisTime)
|
|
suite.StartChain(
|
|
authBuilder.BuildMarshalled(suite.App.AppCodec()),
|
|
NewPricefeedGenStateMultiFromTime(suite.App.AppCodec(), suite.genesisTime),
|
|
NewCDPGenStateMulti(suite.App.AppCodec()),
|
|
incentBuilder.BuildMarshalled(suite.App.AppCodec()),
|
|
)
|
|
|
|
// Setup cdp state containing one CDP
|
|
suite.NoError(
|
|
suite.DeliverMsgCreateCDP(user, initialCollateral, c("usdx", 1e8), collateralType),
|
|
)
|
|
|
|
// Skip ahead a few blocks blocks to accumulate both interest and usdx reward for the cdp
|
|
// Don't sync the CDP between the blocks
|
|
suite.NextBlockAfter(1e6 * time.Second) // about 12 days
|
|
suite.NextBlockAfter(1e6 * time.Second)
|
|
suite.NextBlockAfter(1e6 * time.Second)
|
|
|
|
msg := types.NewMsgClaimUSDXMintingReward(user.String(), "large")
|
|
suite.Require().NoError(suite.DeliverIncentiveMsg(&msg))
|
|
|
|
// The users has always had 100% of cdp debt, so they should receive all rewards for the previous two blocks.
|
|
// Total rewards for each block is block duration * rewards per second
|
|
accuracy := 1e-18 // using a very high accuracy to flag future small calculation changes
|
|
suite.BalanceInEpsilon(user, cs(c(cdptypes.DefaultStableDenom, 1e8), c(types.USDXMintingRewardDenom, 3*1e6*1e6)), accuracy)
|
|
}
|
|
|
|
func (suite *USDXIntegrationTests) TestReinstatingRewardParamsDoesNotTriggerOverPayments() {
|
|
userA := suite.addrs[0]
|
|
userB := suite.addrs[1]
|
|
|
|
authBuilder := app.NewAuthBankGenesisBuilder().
|
|
WithSimpleModuleAccount(kavadisttypes.ModuleName, cs(c(types.USDXMintingRewardDenom, 1e18))). // Fill kavadist with enough coins to pay out any reward
|
|
WithSimpleAccount(userA, cs(c("bnb", 1e10))).
|
|
WithSimpleAccount(userB, cs(c("bnb", 1e10)))
|
|
|
|
incentBuilder := testutil.NewIncentiveGenesisBuilder().
|
|
WithGenesisTime(suite.genesisTime).
|
|
WithMultipliers(types.MultipliersPerDenoms{{
|
|
Denom: types.USDXMintingRewardDenom,
|
|
Multipliers: types.Multipliers{types.NewMultiplier("large", 12, d("1.0"))}, // keep payout at 1.0 to make maths easier
|
|
}}).
|
|
WithSimpleUSDXRewardPeriod("bnb-a", c(types.USDXMintingRewardDenom, 1e6))
|
|
|
|
suite.SetApp()
|
|
suite.WithGenesisTime(suite.genesisTime)
|
|
suite.StartChain(
|
|
authBuilder.BuildMarshalled(suite.App.AppCodec()),
|
|
NewPricefeedGenStateMultiFromTime(suite.App.AppCodec(), suite.genesisTime),
|
|
NewCDPGenStateMulti(suite.App.AppCodec()),
|
|
incentBuilder.BuildMarshalled(suite.App.AppCodec()),
|
|
NewCommitteeGenesisState(suite.App.AppCodec(), 0, userA), // create a committtee to change params
|
|
)
|
|
|
|
// Accumulate some CDP rewards, requires creating a cdp so the total borrowed isn't 0.
|
|
suite.NoError(
|
|
suite.DeliverMsgCreateCDP(userA, c("bnb", 1e10), c("usdx", 1e9), "bnb-a"),
|
|
)
|
|
suite.NextBlockAfter(1e6 * time.Second)
|
|
|
|
// Remove the USDX reward period
|
|
suite.ProposeAndVoteOnNewRewardPeriods(0, userA, types.RewardPeriods{})
|
|
// next block so proposal is enacted
|
|
suite.NextBlockAfter(1 * time.Second)
|
|
|
|
// Create a CDP when there is no reward periods. In a previous version the claim object would not be created, leading to the bug.
|
|
// Withdraw the same amount of usdx as the first cdp currently has. This make the reward maths easier, as rewards will be split 50:50 between each cdp.
|
|
firstCDP, f := suite.App.GetCDPKeeper().GetCdpByOwnerAndCollateralType(suite.Ctx, userA, "bnb-a")
|
|
suite.True(f)
|
|
firstCDPTotalPrincipal := firstCDP.GetTotalPrincipal()
|
|
suite.NoError(
|
|
suite.DeliverMsgCreateCDP(userB, c("bnb", 1e10), firstCDPTotalPrincipal, "bnb-a"),
|
|
)
|
|
|
|
// Add back the reward period
|
|
suite.ProposeAndVoteOnNewRewardPeriods(0, userA,
|
|
types.RewardPeriods{types.NewRewardPeriod(
|
|
true,
|
|
"bnb-a",
|
|
suite.Ctx.BlockTime(), // start accumulating again from this block
|
|
suite.genesisTime.Add(365*24*time.Hour),
|
|
c(types.USDXMintingRewardDenom, 1e6),
|
|
)},
|
|
)
|
|
// next block so proposal is enacted
|
|
suite.NextBlockAfter(1 * time.Second)
|
|
|
|
// Sync the cdp and claim by borrowing a bit
|
|
// In a previous version this would create the cdp with incorrect indexes, leading to overpayment.
|
|
suite.NoError(
|
|
suite.DeliverCDPMsgBorrow(userB, "bnb-a", c(cdptypes.DefaultStableDenom, 1)),
|
|
)
|
|
|
|
// Claim rewards
|
|
msg := types.NewMsgClaimUSDXMintingReward(userB.String(), "large")
|
|
suite.Require().NoError(suite.DeliverIncentiveMsg(&msg))
|
|
|
|
// The cdp had half the total borrows for a 1s block. So should earn half the rewards for that block
|
|
suite.BalanceInEpsilon(
|
|
userB,
|
|
cs(firstCDPTotalPrincipal.Add(c(cdptypes.DefaultStableDenom, 1)), c(types.USDXMintingRewardDenom, 0.5*1e6)),
|
|
1e-18, // using very high accuracy to catch small changes to the calculations
|
|
)
|
|
}
|
|
|
|
// Test suite used for all keeper tests
|
|
type USDXRewardsTestSuite struct {
|
|
suite.Suite
|
|
|
|
keeper keeper.Keeper
|
|
cdpKeeper cdpkeeper.Keeper
|
|
|
|
app app.TestApp
|
|
ctx sdk.Context
|
|
|
|
genesisTime time.Time
|
|
addrs []sdk.AccAddress
|
|
}
|
|
|
|
// SetupTest is run automatically before each suite test
|
|
func (suite *USDXRewardsTestSuite) SetupTest() {
|
|
config := sdk.GetConfig()
|
|
app.SetBech32AddressPrefixes(config)
|
|
|
|
_, suite.addrs = app.GeneratePrivKeyAddressPairs(5)
|
|
|
|
suite.genesisTime = time.Date(2020, 12, 15, 14, 0, 0, 0, time.UTC)
|
|
}
|
|
|
|
func (suite *USDXRewardsTestSuite) SetupApp() {
|
|
suite.app = app.NewTestApp()
|
|
|
|
suite.keeper = suite.app.GetIncentiveKeeper()
|
|
suite.cdpKeeper = suite.app.GetCDPKeeper()
|
|
|
|
suite.ctx = suite.app.NewContext(true, tmproto.Header{Height: 1, Time: suite.genesisTime})
|
|
}
|
|
|
|
func (suite *USDXRewardsTestSuite) SetupWithGenState(authBuilder *app.AuthBankGenesisBuilder, incentBuilder testutil.IncentiveGenesisBuilder) {
|
|
suite.SetupApp()
|
|
|
|
suite.app.InitializeFromGenesisStatesWithTime(
|
|
suite.genesisTime,
|
|
authBuilder.BuildMarshalled(suite.app.AppCodec()),
|
|
NewPricefeedGenStateMultiFromTime(suite.app.AppCodec(), suite.genesisTime),
|
|
NewCDPGenStateMulti(suite.app.AppCodec()),
|
|
incentBuilder.BuildMarshalled(suite.app.AppCodec()),
|
|
)
|
|
}
|
|
|
|
func (suite *USDXRewardsTestSuite) TestAccumulateUSDXMintingRewards() {
|
|
type args struct {
|
|
ctype string
|
|
rewardsPerSecond sdk.Coin
|
|
initialTotalPrincipal sdk.Coin
|
|
timeElapsed int
|
|
expectedRewardFactor sdk.Dec
|
|
}
|
|
type test struct {
|
|
name string
|
|
args args
|
|
}
|
|
testCases := []test{
|
|
{
|
|
"7 seconds",
|
|
args{
|
|
ctype: "bnb-a",
|
|
rewardsPerSecond: c("ukava", 122354),
|
|
initialTotalPrincipal: c("usdx", 1000000000000),
|
|
timeElapsed: 7,
|
|
expectedRewardFactor: d("0.000000856478000000"),
|
|
},
|
|
},
|
|
{
|
|
"1 day",
|
|
args{
|
|
ctype: "bnb-a",
|
|
rewardsPerSecond: c("ukava", 122354),
|
|
initialTotalPrincipal: c("usdx", 1000000000000),
|
|
timeElapsed: 86400,
|
|
expectedRewardFactor: d("0.0105713856"),
|
|
},
|
|
},
|
|
{
|
|
"0 seconds",
|
|
args{
|
|
ctype: "bnb-a",
|
|
rewardsPerSecond: c("ukava", 122354),
|
|
initialTotalPrincipal: c("usdx", 1000000000000),
|
|
timeElapsed: 0,
|
|
expectedRewardFactor: d("0.0"),
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
suite.Run(tc.name, func() {
|
|
incentBuilder := testutil.NewIncentiveGenesisBuilder().WithGenesisTime(suite.genesisTime).WithSimpleUSDXRewardPeriod(tc.args.ctype, tc.args.rewardsPerSecond)
|
|
|
|
suite.SetupWithGenState(app.NewAuthBankGenesisBuilder(), incentBuilder)
|
|
|
|
// setup cdp state
|
|
suite.cdpKeeper.SetTotalPrincipal(suite.ctx, tc.args.ctype, cdptypes.DefaultStableDenom, tc.args.initialTotalPrincipal.Amount)
|
|
|
|
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * tc.args.timeElapsed))
|
|
suite.ctx = suite.ctx.WithBlockTime(updatedBlockTime)
|
|
rewardPeriod, found := suite.keeper.GetUSDXMintingRewardPeriod(suite.ctx, tc.args.ctype)
|
|
suite.Require().True(found)
|
|
suite.keeper.AccumulateUSDXMintingRewards(suite.ctx, rewardPeriod)
|
|
|
|
rewardFactor, _ := suite.keeper.GetUSDXMintingRewardFactor(suite.ctx, tc.args.ctype)
|
|
suite.Require().Equal(tc.args.expectedRewardFactor, rewardFactor)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *USDXRewardsTestSuite) TestSynchronizeUSDXMintingReward() {
|
|
type args struct {
|
|
ctype string
|
|
rewardsPerSecond sdk.Coin
|
|
initialCollateral sdk.Coin
|
|
initialPrincipal sdk.Coin
|
|
blockTimes []int
|
|
expectedRewardFactor sdk.Dec
|
|
expectedRewards sdk.Coin
|
|
}
|
|
type test struct {
|
|
name string
|
|
args args
|
|
}
|
|
|
|
testCases := []test{
|
|
{
|
|
"10 blocks",
|
|
args{
|
|
ctype: "bnb-a",
|
|
rewardsPerSecond: c("ukava", 122354),
|
|
initialCollateral: c("bnb", 1000000000000),
|
|
initialPrincipal: c("usdx", 10000000000),
|
|
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
|
expectedRewardFactor: d("0.001223540000000000"),
|
|
expectedRewards: c("ukava", 12235400),
|
|
},
|
|
},
|
|
{
|
|
"10 blocks - long block time",
|
|
args{
|
|
ctype: "bnb-a",
|
|
rewardsPerSecond: c("ukava", 122354),
|
|
initialCollateral: c("bnb", 1000000000000),
|
|
initialPrincipal: c("usdx", 10000000000),
|
|
blockTimes: []int{86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400},
|
|
expectedRewardFactor: d("10.57138560000000000"),
|
|
expectedRewards: c("ukava", 105713856000),
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
suite.Run(tc.name, func() {
|
|
authBuilder := app.NewAuthBankGenesisBuilder().WithSimpleAccount(suite.addrs[0], cs(tc.args.initialCollateral))
|
|
incentBuilder := testutil.NewIncentiveGenesisBuilder().WithGenesisTime(suite.genesisTime).WithSimpleUSDXRewardPeriod(tc.args.ctype, tc.args.rewardsPerSecond)
|
|
|
|
suite.SetupWithGenState(authBuilder, incentBuilder)
|
|
|
|
// setup cdp state
|
|
err := suite.cdpKeeper.AddCdp(suite.ctx, suite.addrs[0], tc.args.initialCollateral, tc.args.initialPrincipal, tc.args.ctype)
|
|
suite.Require().NoError(err)
|
|
|
|
claim, found := suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[0])
|
|
suite.Require().True(found)
|
|
suite.Require().Equal(sdk.ZeroDec(), claim.RewardIndexes[0].RewardFactor)
|
|
|
|
var timeElapsed int
|
|
previousBlockTime := suite.ctx.BlockTime()
|
|
for _, t := range tc.args.blockTimes {
|
|
timeElapsed += t
|
|
updatedBlockTime := previousBlockTime.Add(time.Duration(int(time.Second) * t))
|
|
previousBlockTime = updatedBlockTime
|
|
blockCtx := suite.ctx.WithBlockTime(updatedBlockTime)
|
|
rewardPeriod, found := suite.keeper.GetUSDXMintingRewardPeriod(blockCtx, tc.args.ctype)
|
|
suite.Require().True(found)
|
|
suite.keeper.AccumulateUSDXMintingRewards(blockCtx, rewardPeriod)
|
|
}
|
|
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * timeElapsed))
|
|
suite.ctx = suite.ctx.WithBlockTime(updatedBlockTime)
|
|
cdp, found := suite.cdpKeeper.GetCdpByOwnerAndCollateralType(suite.ctx, suite.addrs[0], tc.args.ctype)
|
|
suite.Require().True(found)
|
|
suite.Require().NotPanics(func() {
|
|
suite.keeper.SynchronizeUSDXMintingReward(suite.ctx, cdp)
|
|
})
|
|
|
|
rewardFactor, _ := suite.keeper.GetUSDXMintingRewardFactor(suite.ctx, tc.args.ctype)
|
|
suite.Require().Equal(tc.args.expectedRewardFactor, rewardFactor)
|
|
|
|
claim, found = suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[0])
|
|
suite.Require().True(found)
|
|
suite.Require().Equal(tc.args.expectedRewardFactor, claim.RewardIndexes[0].RewardFactor)
|
|
suite.Require().Equal(tc.args.expectedRewards, claim.Reward)
|
|
})
|
|
}
|
|
}
|
|
|
|
func (suite *USDXRewardsTestSuite) TestSimulateUSDXMintingRewardSynchronization() {
|
|
type args struct {
|
|
ctype string
|
|
rewardsPerSecond sdk.Coin
|
|
initialCollateral sdk.Coin
|
|
initialPrincipal sdk.Coin
|
|
blockTimes []int
|
|
expectedRewardFactor sdk.Dec
|
|
expectedRewards sdk.Coin
|
|
}
|
|
type test struct {
|
|
name string
|
|
args args
|
|
}
|
|
|
|
testCases := []test{
|
|
{
|
|
"10 blocks",
|
|
args{
|
|
ctype: "bnb-a",
|
|
rewardsPerSecond: c("ukava", 122354),
|
|
initialCollateral: c("bnb", 1000000000000),
|
|
initialPrincipal: c("usdx", 10000000000),
|
|
blockTimes: []int{10, 10, 10, 10, 10, 10, 10, 10, 10, 10},
|
|
expectedRewardFactor: d("0.001223540000000000"),
|
|
expectedRewards: c("ukava", 12235400),
|
|
},
|
|
},
|
|
{
|
|
"10 blocks - long block time",
|
|
args{
|
|
ctype: "bnb-a",
|
|
rewardsPerSecond: c("ukava", 122354),
|
|
initialCollateral: c("bnb", 1000000000000),
|
|
initialPrincipal: c("usdx", 10000000000),
|
|
blockTimes: []int{86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400, 86400},
|
|
expectedRewardFactor: d("10.57138560000000000"),
|
|
expectedRewards: c("ukava", 105713856000),
|
|
},
|
|
},
|
|
}
|
|
for _, tc := range testCases {
|
|
suite.Run(tc.name, func() {
|
|
authBuilder := app.NewAuthBankGenesisBuilder().WithSimpleAccount(suite.addrs[0], cs(tc.args.initialCollateral))
|
|
incentBuilder := testutil.NewIncentiveGenesisBuilder().WithGenesisTime(suite.genesisTime).WithSimpleUSDXRewardPeriod(tc.args.ctype, tc.args.rewardsPerSecond)
|
|
|
|
suite.SetupWithGenState(authBuilder, incentBuilder)
|
|
|
|
// setup cdp state
|
|
err := suite.cdpKeeper.AddCdp(suite.ctx, suite.addrs[0], tc.args.initialCollateral, tc.args.initialPrincipal, tc.args.ctype)
|
|
suite.Require().NoError(err)
|
|
|
|
claim, found := suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[0])
|
|
suite.Require().True(found)
|
|
suite.Require().Equal(sdk.ZeroDec(), claim.RewardIndexes[0].RewardFactor)
|
|
|
|
var timeElapsed int
|
|
previousBlockTime := suite.ctx.BlockTime()
|
|
for _, t := range tc.args.blockTimes {
|
|
timeElapsed += t
|
|
updatedBlockTime := previousBlockTime.Add(time.Duration(int(time.Second) * t))
|
|
previousBlockTime = updatedBlockTime
|
|
blockCtx := suite.ctx.WithBlockTime(updatedBlockTime)
|
|
rewardPeriod, found := suite.keeper.GetUSDXMintingRewardPeriod(blockCtx, tc.args.ctype)
|
|
suite.Require().True(found)
|
|
suite.keeper.AccumulateUSDXMintingRewards(blockCtx, rewardPeriod)
|
|
}
|
|
updatedBlockTime := suite.ctx.BlockTime().Add(time.Duration(int(time.Second) * timeElapsed))
|
|
suite.ctx = suite.ctx.WithBlockTime(updatedBlockTime)
|
|
|
|
claim, found = suite.keeper.GetUSDXMintingClaim(suite.ctx, suite.addrs[0])
|
|
suite.Require().True(found)
|
|
suite.Require().Equal(claim.RewardIndexes[0].RewardFactor, sdk.ZeroDec())
|
|
suite.Require().Equal(claim.Reward, sdk.NewCoin("ukava", sdk.ZeroInt()))
|
|
|
|
updatedClaim := suite.keeper.SimulateUSDXMintingSynchronization(suite.ctx, claim)
|
|
suite.Require().Equal(tc.args.expectedRewardFactor, updatedClaim.RewardIndexes[0].RewardFactor)
|
|
suite.Require().Equal(tc.args.expectedRewards, updatedClaim.Reward)
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestUSDXRewardsTestSuite(t *testing.T) {
|
|
suite.Run(t, new(USDXRewardsTestSuite))
|
|
}
|