mirror of
				https://github.com/0glabs/0g-chain.git
				synced 2025-10-31 22:37:26 +00:00 
			
		
		
		
	feat(community): consolidate community funds (#1729)
* Add consolidate methods * Update distr feepool balance with dust, add tests * Set params for proposal handler to not influence module balances * Add StakingRewardsPerSecond param for proposal test * Update changelog * Update test to check emitted events * Log dust amounts for x/distribution * Modify feepool communitypool field instead of entire replacement * Update tests to include cases with empty balances * Move EventsContains to app * Remove extra copied ModuleName * Add Require() to incentive claims in tests to reduce errors * Move consolidate tests to testutil * Only transfer non-ukava coins * Add DefaultStakingRewardsState to proposal handler test * Move event emit before consolidate * add golangci specific timeout --------- Co-authored-by: Nick DeLuca <nickdeluca08@gmail.com>
This commit is contained in:
		
							parent
							
								
									395b69ac2f
								
							
						
					
					
						commit
						8186367c8b
					
				
							
								
								
									
										1
									
								
								.github/workflows/ci-lint.yml
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										1
									
								
								.github/workflows/ci-lint.yml
									
									
									
									
										vendored
									
									
								
							| @ -14,3 +14,4 @@ jobs: | |||||||
|         with: |         with: | ||||||
|           github_token: ${{ secrets.github_token }} |           github_token: ${{ secrets.github_token }} | ||||||
|           reporter: github-pr-review |           reporter: github-pr-review | ||||||
|  |           golangci_lint_flags: --timeout 10m | ||||||
|  | |||||||
| @ -53,6 +53,7 @@ Ref: https://keepachangelog.com/en/1.0.0/ | |||||||
| - (community) [#1704] Add param to control when inflation will be disabled | - (community) [#1704] Add param to control when inflation will be disabled | ||||||
| - (community) [#1707] Default staking rewards per second set to `744191` | - (community) [#1707] Default staking rewards per second set to `744191` | ||||||
| - (community) [#1706] Add disable inflation upgrade to begin blocker that updates x/mint and x/kavadist params. | - (community) [#1706] Add disable inflation upgrade to begin blocker that updates x/mint and x/kavadist params. | ||||||
|  | - (community) [#1729] Consolidate community funds from `x/distribution` and `x/kavadist` to `x/community` | ||||||
| 
 | 
 | ||||||
| ## [v0.24.0] | ## [v0.24.0] | ||||||
| 
 | 
 | ||||||
| @ -293,6 +294,7 @@ the [changelog](https://github.com/cosmos/cosmos-sdk/blob/v0.38.4/CHANGELOG.md). | |||||||
| - [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run | - [#257](https://github.com/Kava-Labs/kava/pulls/257) Include scripts to run | ||||||
|   large-scale simulations remotely using aws-batch |   large-scale simulations remotely using aws-batch | ||||||
| 
 | 
 | ||||||
|  | [#1729]: https://github.com/Kava-Labs/kava/pull/1729 | ||||||
| [#1745]: https://github.com/Kava-Labs/kava/pull/1745 | [#1745]: https://github.com/Kava-Labs/kava/pull/1745 | ||||||
| [#1707]: https://github.com/Kava-Labs/kava/pull/1707 | [#1707]: https://github.com/Kava-Labs/kava/pull/1707 | ||||||
| [#1706]: https://github.com/Kava-Labs/kava/pull/1706 | [#1706]: https://github.com/Kava-Labs/kava/pull/1706 | ||||||
|  | |||||||
							
								
								
									
										104
									
								
								x/community/keeper/consolidate.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										104
									
								
								x/community/keeper/consolidate.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,104 @@ | |||||||
|  | package keeper | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"fmt" | ||||||
|  | 
 | ||||||
|  | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
|  | 	"github.com/kava-labs/kava/x/community/types" | ||||||
|  | 
 | ||||||
|  | 	kavadisttypes "github.com/kava-labs/kava/x/kavadist/types" | ||||||
|  | 
 | ||||||
|  | 	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | // StartCommunityFundConsolidation consolidates the community funds from
 | ||||||
|  | // x/distribution and x/kavadist into the x/community module account
 | ||||||
|  | func (k Keeper) StartCommunityFundConsolidation(ctx sdk.Context) error { | ||||||
|  | 	logger := k.Logger(ctx) | ||||||
|  | 	logger.Info("community fund consolidation upgrade started") | ||||||
|  | 
 | ||||||
|  | 	// Consolidate x/distribution community pool
 | ||||||
|  | 	if err := k.consolidateCommunityDistribution(ctx); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Consolidate x/kavadist account
 | ||||||
|  | 	if err := k.consolidateCommunityKavadist(ctx); err != nil { | ||||||
|  | 		return err | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Log new x/community balance
 | ||||||
|  | 	communityCoins := k.GetModuleAccountBalance(ctx) | ||||||
|  | 	logger.Info(fmt.Sprintf("community funds consolidated, x/community balance is now %s", communityCoins)) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // consolidateCommunityDistribution transfers all coins from the x/distribution
 | ||||||
|  | // community pool to the x/community module account
 | ||||||
|  | func (k Keeper) consolidateCommunityDistribution(ctx sdk.Context) error { | ||||||
|  | 	logger := k.Logger(ctx) | ||||||
|  | 
 | ||||||
|  | 	// Get community coins with leftover leftoverDust
 | ||||||
|  | 	truncatedCoins, leftoverDust := k.distrKeeper. | ||||||
|  | 		GetFeePoolCommunityCoins(ctx). | ||||||
|  | 		TruncateDecimal() | ||||||
|  | 
 | ||||||
|  | 	// Transfer to x/community
 | ||||||
|  | 	err := k.bankKeeper.SendCoinsFromModuleToModule( | ||||||
|  | 		ctx, | ||||||
|  | 		distrtypes.ModuleName, // sender
 | ||||||
|  | 		types.ModuleName,      // recipient
 | ||||||
|  | 		truncatedCoins, | ||||||
|  | 	) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("failed to transfer x/distribution coins to x/community: %w", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	logger.Info(fmt.Sprintf("transferred %s from x/distribution to x/community", truncatedCoins)) | ||||||
|  | 
 | ||||||
|  | 	// Set x/distribution community pool to remaining dust amounts
 | ||||||
|  | 	feePool := k.distrKeeper.GetFeePool(ctx) | ||||||
|  | 	feePool.CommunityPool = leftoverDust | ||||||
|  | 	k.distrKeeper.SetFeePool(ctx, feePool) | ||||||
|  | 
 | ||||||
|  | 	logger.Info(fmt.Sprintf("remaining x/distribution community pool dust: %s", leftoverDust)) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | // consolidateCommunityKavadist transfers all coins from the x/kavadist module
 | ||||||
|  | // account to the x/community module account
 | ||||||
|  | func (k Keeper) consolidateCommunityKavadist(ctx sdk.Context) error { | ||||||
|  | 	logger := k.Logger(ctx) | ||||||
|  | 
 | ||||||
|  | 	kavadistAcc := k.accountKeeper.GetModuleAccount(ctx, kavadisttypes.KavaDistMacc) | ||||||
|  | 	transferCoins := k.bankKeeper.GetAllBalances(ctx, kavadistAcc.GetAddress()) | ||||||
|  | 
 | ||||||
|  | 	// Remove ukava from transfer coins - ony transfer non-ukava coins
 | ||||||
|  | 	found, kavaCoins := transferCoins.Find("ukava") | ||||||
|  | 	if found { | ||||||
|  | 		transferCoins = transferCoins.Sub(kavaCoins) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Transfer remaining coins to x/community
 | ||||||
|  | 	err := k.bankKeeper.SendCoinsFromModuleToModule( | ||||||
|  | 		ctx, | ||||||
|  | 		kavadisttypes.ModuleName, // sender
 | ||||||
|  | 		types.ModuleName,         // recipient
 | ||||||
|  | 		transferCoins, | ||||||
|  | 	) | ||||||
|  | 	if err != nil { | ||||||
|  | 		return fmt.Errorf("failed to transfer x/kavadist coins to x/community: %w", err) | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	kavadistRemainingCoins := k.bankKeeper.GetAllBalances(ctx, kavadistAcc.GetAddress()) | ||||||
|  | 
 | ||||||
|  | 	logger.Info(fmt.Sprintf( | ||||||
|  | 		"transferred %s from x/kavadist to x/community, remaining x/kavadist balance: %s", | ||||||
|  | 		transferCoins, | ||||||
|  | 		kavadistRemainingCoins, | ||||||
|  | 	)) | ||||||
|  | 
 | ||||||
|  | 	return nil | ||||||
|  | } | ||||||
| @ -22,17 +22,21 @@ func (k Keeper) CheckAndDisableMintAndKavaDistInflation(ctx sdk.Context) { | |||||||
| 	// run disable inflation logic
 | 	// run disable inflation logic
 | ||||||
| 	k.disableInflation(ctx) | 	k.disableInflation(ctx) | ||||||
| 
 | 
 | ||||||
|  | 	ctx.EventManager().EmitEvent( | ||||||
|  | 		sdk.NewEvent( | ||||||
|  | 			types.EventTypeInflationStop, | ||||||
|  | 		), | ||||||
|  | 	) | ||||||
|  | 
 | ||||||
| 	// reset disable inflation time to ensure next call is a no-op
 | 	// reset disable inflation time to ensure next call is a no-op
 | ||||||
| 	params.UpgradeTimeDisableInflation = time.Time{} | 	params.UpgradeTimeDisableInflation = time.Time{} | ||||||
| 	// set staking rewards to provided intial value
 | 	// set staking rewards to provided intial value
 | ||||||
| 	params.StakingRewardsPerSecond = params.UpgradeTimeSetStakingRewardsPerSecond | 	params.StakingRewardsPerSecond = params.UpgradeTimeSetStakingRewardsPerSecond | ||||||
| 	k.SetParams(ctx, params) | 	k.SetParams(ctx, params) | ||||||
| 
 | 
 | ||||||
| 	ctx.EventManager().EmitEvent( | 	if err := k.StartCommunityFundConsolidation(ctx); err != nil { | ||||||
| 		sdk.NewEvent( | 		panic(err) | ||||||
| 			types.EventTypeInflationStop, | 	} | ||||||
| 		), |  | ||||||
| 	) |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // TODO: double check this is correct method for disabling inflation in kavadist without
 | // TODO: double check this is correct method for disabling inflation in kavadist without
 | ||||||
|  | |||||||
| @ -16,6 +16,7 @@ type Keeper struct { | |||||||
| 	key storetypes.StoreKey | 	key storetypes.StoreKey | ||||||
| 	cdc codec.Codec | 	cdc codec.Codec | ||||||
| 
 | 
 | ||||||
|  | 	accountKeeper  types.AccountKeeper | ||||||
| 	bankKeeper     types.BankKeeper | 	bankKeeper     types.BankKeeper | ||||||
| 	cdpKeeper      types.CdpKeeper | 	cdpKeeper      types.CdpKeeper | ||||||
| 	distrKeeper    types.DistributionKeeper | 	distrKeeper    types.DistributionKeeper | ||||||
| @ -63,6 +64,7 @@ func NewKeeper( | |||||||
| 		key: key, | 		key: key, | ||||||
| 		cdc: cdc, | 		cdc: cdc, | ||||||
| 
 | 
 | ||||||
|  | 		accountKeeper:  ak, | ||||||
| 		bankKeeper:     bk, | 		bankKeeper:     bk, | ||||||
| 		cdpKeeper:      ck, | 		cdpKeeper:      ck, | ||||||
| 		distrKeeper:    dk, | 		distrKeeper:    dk, | ||||||
|  | |||||||
| @ -5,6 +5,7 @@ import ( | |||||||
| 	"testing" | 	"testing" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | 	sdkmath "cosmossdk.io/math" | ||||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
| 	"github.com/stretchr/testify/suite" | 	"github.com/stretchr/testify/suite" | ||||||
| 	abcitypes "github.com/tendermint/tendermint/abci/types" | 	abcitypes "github.com/tendermint/tendermint/abci/types" | ||||||
| @ -27,9 +28,11 @@ func c(denom string, amount int64) sdk.Coin { return sdk.NewInt64Coin(denom, amo | |||||||
| func ukava(amt int64) sdk.Coins { | func ukava(amt int64) sdk.Coins { | ||||||
| 	return sdk.NewCoins(c("ukava", amt)) | 	return sdk.NewCoins(c("ukava", amt)) | ||||||
| } | } | ||||||
|  | 
 | ||||||
| func usdx(amt int64) sdk.Coins { | func usdx(amt int64) sdk.Coins { | ||||||
| 	return sdk.NewCoins(c("usdx", amt)) | 	return sdk.NewCoins(c("usdx", amt)) | ||||||
| } | } | ||||||
|  | 
 | ||||||
| func otherdenom(amt int64) sdk.Coins { | func otherdenom(amt int64) sdk.Coins { | ||||||
| 	return sdk.NewCoins(c("other-denom", amt)) | 	return sdk.NewCoins(c("other-denom", amt)) | ||||||
| } | } | ||||||
| @ -67,10 +70,19 @@ func (suite *proposalTestSuite) SetupTest() { | |||||||
| 		ChainID: chainID, | 		ChainID: chainID, | ||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
|  | 	// Set UpgradeTimeDisableInflation to far future to not influence module
 | ||||||
|  | 	// account balances
 | ||||||
|  | 	params := types.Params{ | ||||||
|  | 		UpgradeTimeDisableInflation: time.Now().Add(100000 * time.Hour), | ||||||
|  | 		StakingRewardsPerSecond:     sdkmath.LegacyNewDec(0), | ||||||
|  | 	} | ||||||
|  | 	communityGs := types.NewGenesisState(params, types.DefaultStakingRewardsState()) | ||||||
|  | 
 | ||||||
| 	tApp.InitializeFromGenesisStatesWithTimeAndChainID( | 	tApp.InitializeFromGenesisStatesWithTimeAndChainID( | ||||||
| 		genTime, chainID, | 		genTime, chainID, | ||||||
| 		app.GenesisState{hardtypes.ModuleName: tApp.AppCodec().MustMarshalJSON(&hardGS)}, | 		app.GenesisState{hardtypes.ModuleName: tApp.AppCodec().MustMarshalJSON(&hardGS)}, | ||||||
| 		app.GenesisState{pricefeedtypes.ModuleName: tApp.AppCodec().MustMarshalJSON(&pricefeedGS)}, | 		app.GenesisState{pricefeedtypes.ModuleName: tApp.AppCodec().MustMarshalJSON(&pricefeedGS)}, | ||||||
|  | 		app.GenesisState{types.ModuleName: tApp.AppCodec().MustMarshalJSON(&communityGs)}, | ||||||
| 		testutil.NewCDPGenState(tApp.AppCodec(), "ukava", "kava", sdk.NewDec(2)), | 		testutil.NewCDPGenState(tApp.AppCodec(), "ukava", "kava", sdk.NewDec(2)), | ||||||
| 	) | 	) | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -11,10 +11,6 @@ import ( | |||||||
| 	"github.com/kava-labs/kava/x/community/types" | 	"github.com/kava-labs/kava/x/community/types" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| const ( |  | ||||||
| 	ModuleName = "mint" |  | ||||||
| ) |  | ||||||
| 
 |  | ||||||
| // Migrate migrates the x/community module state from the consensus version 1 to
 | // Migrate migrates the x/community module state from the consensus version 1 to
 | ||||||
| // version 2. Specifically, sets new parameters in the module state.
 | // version 2. Specifically, sets new parameters in the module state.
 | ||||||
| func Migrate( | func Migrate( | ||||||
|  | |||||||
							
								
								
									
										180
									
								
								x/community/testutil/consolidate.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								x/community/testutil/consolidate.go
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,180 @@ | |||||||
|  | package testutil | ||||||
|  | 
 | ||||||
|  | import ( | ||||||
|  | 	"time" | ||||||
|  | 
 | ||||||
|  | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
|  | 	banktypes "github.com/cosmos/cosmos-sdk/x/bank/types" | ||||||
|  | 
 | ||||||
|  | 	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" | ||||||
|  | 	"github.com/kava-labs/kava/app" | ||||||
|  | 	types "github.com/kava-labs/kava/x/community/types" | ||||||
|  | 	kavadisttypes "github.com/kava-labs/kava/x/kavadist/types" | ||||||
|  | ) | ||||||
|  | 
 | ||||||
|  | func (suite *disableInflationTestSuite) TestStartCommunityFundConsolidation() { | ||||||
|  | 	tests := []struct { | ||||||
|  | 		name                   string | ||||||
|  | 		initialFeePoolCoins    sdk.DecCoins | ||||||
|  | 		initialKavadistBalance sdk.Coins | ||||||
|  | 	}{ | ||||||
|  | 		{ | ||||||
|  | 			"basic test with both balances and dust", | ||||||
|  | 			sdk.NewDecCoins( | ||||||
|  | 				sdk.NewDecCoinFromDec("ukava", sdk.NewDecWithPrec(123456, 2)), | ||||||
|  | 				sdk.NewDecCoinFromDec("usdx", sdk.NewDecWithPrec(654321, 3)), | ||||||
|  | 			), | ||||||
|  | 			sdk.NewCoins( | ||||||
|  | 				sdk.NewInt64Coin("ukava", 10_000), | ||||||
|  | 				sdk.NewInt64Coin("usdx", 10_000), | ||||||
|  | 			), | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"empty x/distribution feepool", | ||||||
|  | 			sdk.DecCoins(nil), | ||||||
|  | 			sdk.NewCoins( | ||||||
|  | 				sdk.NewInt64Coin("ukava", 10_000), | ||||||
|  | 				sdk.NewInt64Coin("usdx", 10_000), | ||||||
|  | 			), | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"empty x/kavadist balance", | ||||||
|  | 			sdk.NewDecCoins( | ||||||
|  | 				sdk.NewDecCoinFromDec("ukava", sdk.NewDecWithPrec(123456, 2)), | ||||||
|  | 				sdk.NewDecCoinFromDec("usdx", sdk.NewDecWithPrec(654321, 3)), | ||||||
|  | 			), | ||||||
|  | 			sdk.Coins{}, | ||||||
|  | 		}, | ||||||
|  | 		{ | ||||||
|  | 			"both x/distribution feepool and x/kavadist balance empty", | ||||||
|  | 			sdk.DecCoins(nil), | ||||||
|  | 			sdk.Coins{}, | ||||||
|  | 		}, | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	for _, tc := range tests { | ||||||
|  | 		suite.Run(tc.name, func() { | ||||||
|  | 			suite.SetupTest() | ||||||
|  | 			ak := suite.App.GetAccountKeeper() | ||||||
|  | 
 | ||||||
|  | 			initialFeePool := distrtypes.FeePool{ | ||||||
|  | 				CommunityPool: tc.initialFeePoolCoins, | ||||||
|  | 			} | ||||||
|  | 
 | ||||||
|  | 			initialFeePoolCoins, initialFeePoolDust := initialFeePool.CommunityPool.TruncateDecimal() | ||||||
|  | 
 | ||||||
|  | 			// More coins than initial feepool/communitypool
 | ||||||
|  | 			fundCoins := sdk.NewCoins( | ||||||
|  | 				sdk.NewInt64Coin("ukava", 10_000), | ||||||
|  | 				sdk.NewInt64Coin("usdx", 10_000), | ||||||
|  | 			) | ||||||
|  | 
 | ||||||
|  | 			// Always fund x/distribution with enough coins to cover feepool
 | ||||||
|  | 			err := suite.App.FundModuleAccount( | ||||||
|  | 				suite.Ctx, | ||||||
|  | 				distrtypes.ModuleName, | ||||||
|  | 				fundCoins, | ||||||
|  | 			) | ||||||
|  | 			suite.NoError(err, "x/distribution account should be funded without error") | ||||||
|  | 
 | ||||||
|  | 			err = suite.App.FundModuleAccount( | ||||||
|  | 				suite.Ctx, | ||||||
|  | 				kavadisttypes.ModuleName, | ||||||
|  | 				tc.initialKavadistBalance, | ||||||
|  | 			) | ||||||
|  | 			suite.NoError(err, "x/kavadist account should be funded without error") | ||||||
|  | 
 | ||||||
|  | 			suite.App.GetDistrKeeper().SetFeePool(suite.Ctx, initialFeePool) | ||||||
|  | 
 | ||||||
|  | 			// Ensure the feepool was set before migration
 | ||||||
|  | 			feePoolBefore := suite.App.GetDistrKeeper().GetFeePool(suite.Ctx) | ||||||
|  | 			suite.Equal(initialFeePool, feePoolBefore, "initial feepool should be set") | ||||||
|  | 			communityBalanceBefore := suite.App.GetCommunityKeeper().GetModuleAccountBalance(suite.Ctx) | ||||||
|  | 
 | ||||||
|  | 			kavadistAcc := ak.GetModuleAccount(suite.Ctx, kavadisttypes.KavaDistMacc) | ||||||
|  | 			kavaDistCoinsBefore := suite.App.GetBankKeeper().GetAllBalances(suite.Ctx, kavadistAcc.GetAddress()) | ||||||
|  | 			suite.Equal( | ||||||
|  | 				tc.initialKavadistBalance, | ||||||
|  | 				kavaDistCoinsBefore, | ||||||
|  | 				"x/kavadist balance should be funded", | ||||||
|  | 			) | ||||||
|  | 
 | ||||||
|  | 			expectedKavaDistCoins := sdk.NewCoins(sdk.NewCoin("ukava", kavaDistCoinsBefore.AmountOf("ukava"))) | ||||||
|  | 
 | ||||||
|  | 			// -------------
 | ||||||
|  | 			// Run upgrade
 | ||||||
|  | 
 | ||||||
|  | 			params, found := suite.Keeper.GetParams(suite.Ctx) | ||||||
|  | 			suite.Require().True(found) | ||||||
|  | 			params.UpgradeTimeDisableInflation = suite.Ctx.BlockTime().Add(-time.Minute) | ||||||
|  | 			suite.Keeper.SetParams(suite.Ctx, params) | ||||||
|  | 
 | ||||||
|  | 			err = suite.Keeper.StartCommunityFundConsolidation(suite.Ctx) | ||||||
|  | 			suite.NoError(err, "consolidation should not error") | ||||||
|  | 
 | ||||||
|  | 			// -------------
 | ||||||
|  | 			// Check results
 | ||||||
|  | 			suite.Run("module balances after consolidation should moved", func() { | ||||||
|  | 				feePoolAfter := suite.App.GetDistrKeeper().GetFeePool(suite.Ctx) | ||||||
|  | 				suite.Equal( | ||||||
|  | 					initialFeePoolDust, | ||||||
|  | 					feePoolAfter.CommunityPool, | ||||||
|  | 					"x/distribution community pool should be sent to x/community", | ||||||
|  | 				) | ||||||
|  | 
 | ||||||
|  | 				kavaDistCoinsAfter := suite.App.GetBankKeeper().GetAllBalances(suite.Ctx, kavadistAcc.GetAddress()) | ||||||
|  | 				suite.Equal( | ||||||
|  | 					expectedKavaDistCoins, | ||||||
|  | 					kavaDistCoinsAfter, | ||||||
|  | 					"x/kavadist balance should ony contain ukava", | ||||||
|  | 				) | ||||||
|  | 
 | ||||||
|  | 				totalExpectedCommunityPoolCoins := communityBalanceBefore. | ||||||
|  | 					Add(initialFeePoolCoins...).      // x/distribution fee pool
 | ||||||
|  | 					Add(tc.initialKavadistBalance...) // x/kavadist module balance
 | ||||||
|  | 
 | ||||||
|  | 				communityBalanceAfter := suite.App.GetCommunityKeeper().GetModuleAccountBalance(suite.Ctx) | ||||||
|  | 
 | ||||||
|  | 				// Use .IsAllGTE to avoid types.Coins(nil) vs types.Coins{} mismatch
 | ||||||
|  | 				suite.Truef( | ||||||
|  | 					totalExpectedCommunityPoolCoins.IsAllGTE(communityBalanceAfter), | ||||||
|  | 					"x/community balance should be increased by the truncated x/distribution community pool, got %s, expected %s", | ||||||
|  | 					communityBalanceAfter, | ||||||
|  | 					totalExpectedCommunityPoolCoins, | ||||||
|  | 				) | ||||||
|  | 			}) | ||||||
|  | 
 | ||||||
|  | 			suite.Run("bank transfer events should be emitted", func() { | ||||||
|  | 				communityAcc := ak.GetModuleAccount(suite.Ctx, types.ModuleAccountName) | ||||||
|  | 				distributionAcc := ak.GetModuleAccount(suite.Ctx, distrtypes.ModuleName) | ||||||
|  | 				kavadistAcc := ak.GetModuleAccount(suite.Ctx, kavadisttypes.KavaDistMacc) | ||||||
|  | 
 | ||||||
|  | 				events := suite.Ctx.EventManager().Events() | ||||||
|  | 
 | ||||||
|  | 				suite.NoError( | ||||||
|  | 					app.EventsContains( | ||||||
|  | 						events, | ||||||
|  | 						sdk.NewEvent( | ||||||
|  | 							banktypes.EventTypeTransfer, | ||||||
|  | 							sdk.NewAttribute(banktypes.AttributeKeyRecipient, communityAcc.GetAddress().String()), | ||||||
|  | 							sdk.NewAttribute(banktypes.AttributeKeySender, distributionAcc.GetAddress().String()), | ||||||
|  | 							sdk.NewAttribute(sdk.AttributeKeyAmount, initialFeePoolCoins.String()), | ||||||
|  | 						), | ||||||
|  | 					), | ||||||
|  | 				) | ||||||
|  | 
 | ||||||
|  | 				suite.NoError( | ||||||
|  | 					app.EventsContains( | ||||||
|  | 						events, | ||||||
|  | 						sdk.NewEvent( | ||||||
|  | 							banktypes.EventTypeTransfer, | ||||||
|  | 							sdk.NewAttribute(banktypes.AttributeKeyRecipient, communityAcc.GetAddress().String()), | ||||||
|  | 							sdk.NewAttribute(banktypes.AttributeKeySender, kavadistAcc.GetAddress().String()), | ||||||
|  | 							sdk.NewAttribute(sdk.AttributeKeyAmount, kavaDistCoinsBefore.Sub(expectedKavaDistCoins...).String()), | ||||||
|  | 						), | ||||||
|  | 					), | ||||||
|  | 				) | ||||||
|  | 			}) | ||||||
|  | 		}) | ||||||
|  | 	} | ||||||
|  | } | ||||||
| @ -3,6 +3,7 @@ package types | |||||||
| import ( | import ( | ||||||
| 	sdk "github.com/cosmos/cosmos-sdk/types" | 	sdk "github.com/cosmos/cosmos-sdk/types" | ||||||
| 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | 	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types" | ||||||
|  | 	distrtypes "github.com/cosmos/cosmos-sdk/x/distribution/types" | ||||||
| 	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" | 	minttypes "github.com/cosmos/cosmos-sdk/x/mint/types" | ||||||
| 	kavadisttypes "github.com/kava-labs/kava/x/kavadist/types" | 	kavadisttypes "github.com/kava-labs/kava/x/kavadist/types" | ||||||
| ) | ) | ||||||
| @ -40,6 +41,8 @@ type DistributionKeeper interface { | |||||||
| 	DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error | 	DistributeFromFeePool(ctx sdk.Context, amount sdk.Coins, receiveAddr sdk.AccAddress) error | ||||||
| 	FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error | 	FundCommunityPool(ctx sdk.Context, amount sdk.Coins, sender sdk.AccAddress) error | ||||||
| 	GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins | 	GetFeePoolCommunityCoins(ctx sdk.Context) sdk.DecCoins | ||||||
|  | 	GetFeePool(ctx sdk.Context) distrtypes.FeePool | ||||||
|  | 	SetFeePool(ctx sdk.Context, feePool distrtypes.FeePool) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type MintKeeper interface { | type MintKeeper interface { | ||||||
|  | |||||||
| @ -47,7 +47,7 @@ func (suite *HandlerTestSuite) TestPayoutDelegatorClaimMultiDenom() { | |||||||
| 
 | 
 | ||||||
| 	// Claim denoms
 | 	// Claim denoms
 | ||||||
| 	err := suite.DeliverIncentiveMsg(&msg) | 	err := suite.DeliverIncentiveMsg(&msg) | ||||||
| 	suite.NoError(err) | 	suite.Require().NoError(err) | ||||||
| 
 | 
 | ||||||
| 	// Check rewards were paid out
 | 	// Check rewards were paid out
 | ||||||
| 	expectedRewardsHard := c("hard", int64(0.2*float64(2*7*1e6))) | 	expectedRewardsHard := c("hard", int64(0.2*float64(2*7*1e6))) | ||||||
| @ -97,7 +97,7 @@ func (suite *HandlerTestSuite) TestPayoutDelegatorClaimSingleDenom() { | |||||||
| 
 | 
 | ||||||
| 	// Claim rewards
 | 	// Claim rewards
 | ||||||
| 	err := suite.DeliverIncentiveMsg(&msg) | 	err := suite.DeliverIncentiveMsg(&msg) | ||||||
| 	suite.NoError(err) | 	suite.Require().NoError(err) | ||||||
| 
 | 
 | ||||||
| 	// Check rewards were paid out
 | 	// Check rewards were paid out
 | ||||||
| 	expectedRewards := c("swap", 2*7*1e6) | 	expectedRewards := c("swap", 2*7*1e6) | ||||||
|  | |||||||
| @ -40,7 +40,7 @@ func (suite *HandlerTestSuite) TestPayoutHardClaimMultiDenom() { | |||||||
| 
 | 
 | ||||||
| 	// Claim denoms
 | 	// Claim denoms
 | ||||||
| 	err := suite.DeliverIncentiveMsg(&msg) | 	err := suite.DeliverIncentiveMsg(&msg) | ||||||
| 	suite.NoError(err) | 	suite.Require().NoError(err) | ||||||
| 
 | 
 | ||||||
| 	// Check rewards were paid out
 | 	// Check rewards were paid out
 | ||||||
| 	expectedRewardsHard := c("hard", int64(0.2*float64(2*7*1e6))) | 	expectedRewardsHard := c("hard", int64(0.2*float64(2*7*1e6))) | ||||||
| @ -85,7 +85,7 @@ func (suite *HandlerTestSuite) TestPayoutHardClaimSingleDenom() { | |||||||
| 
 | 
 | ||||||
| 	// Claim rewards
 | 	// Claim rewards
 | ||||||
| 	err := suite.DeliverIncentiveMsg(&msg) | 	err := suite.DeliverIncentiveMsg(&msg) | ||||||
| 	suite.NoError(err) | 	suite.Require().NoError(err) | ||||||
| 
 | 
 | ||||||
| 	// Check rewards were paid out
 | 	// Check rewards were paid out
 | ||||||
| 	expectedRewards := c("swap", 2*7*1e6) | 	expectedRewards := c("swap", 2*7*1e6) | ||||||
|  | |||||||
| @ -130,7 +130,7 @@ func (suite *HandlerTestSuite) TestPayoutSwapClaimMultiDenom() { | |||||||
| 
 | 
 | ||||||
| 	// Claim rewards
 | 	// Claim rewards
 | ||||||
| 	err := suite.DeliverIncentiveMsg(&msg) | 	err := suite.DeliverIncentiveMsg(&msg) | ||||||
| 	suite.NoError(err) | 	suite.Require().NoError(err) | ||||||
| 
 | 
 | ||||||
| 	// Check rewards were paid out
 | 	// Check rewards were paid out
 | ||||||
| 	expectedRewardsHard := c("hard", int64(0.2*float64(7*1e6))) | 	expectedRewardsHard := c("hard", int64(0.2*float64(7*1e6))) | ||||||
| @ -176,7 +176,7 @@ func (suite *HandlerTestSuite) TestPayoutSwapClaimSingleDenom() { | |||||||
| 
 | 
 | ||||||
| 	// Claim rewards
 | 	// Claim rewards
 | ||||||
| 	err := suite.DeliverIncentiveMsg(&msg) | 	err := suite.DeliverIncentiveMsg(&msg) | ||||||
| 	suite.NoError(err) | 	suite.Require().NoError(err) | ||||||
| 
 | 
 | ||||||
| 	// Check rewards were paid out
 | 	// Check rewards were paid out
 | ||||||
| 	expectedRewards := c("swap", 7*1e6) | 	expectedRewards := c("swap", 7*1e6) | ||||||
|  | |||||||
| @ -32,7 +32,7 @@ func (suite *HandlerTestSuite) TestPayoutUSDXClaim() { | |||||||
| 
 | 
 | ||||||
| 	// Claim a single denom
 | 	// Claim a single denom
 | ||||||
| 	err = suite.DeliverIncentiveMsg(&msg) | 	err = suite.DeliverIncentiveMsg(&msg) | ||||||
| 	suite.NoError(err) | 	suite.Require().NoError(err) | ||||||
| 
 | 
 | ||||||
| 	// Check rewards were paid out
 | 	// Check rewards were paid out
 | ||||||
| 	expectedRewards := cs(c(types.USDXMintingRewardDenom, 7*1e6)) | 	expectedRewards := cs(c(types.USDXMintingRewardDenom, 7*1e6)) | ||||||
|  | |||||||
| @ -86,7 +86,7 @@ func (suite *BorrowIntegrationTests) TestSingleUserAccumulatesRewardsAfterSyncin | |||||||
| 	}) | 	}) | ||||||
| 
 | 
 | ||||||
| 	// User claims all their rewards
 | 	// User claims all their rewards
 | ||||||
| 	suite.NoError(suite.DeliverIncentiveMsg(&msg)) | 	suite.Require().NoError(suite.DeliverIncentiveMsg(&msg)) | ||||||
| 
 | 
 | ||||||
| 	// The users has always had 100% of borrows, so they should receive all rewards for the previous two blocks.
 | 	// The users has always had 100% of borrows, so they should receive all rewards for the previous two blocks.
 | ||||||
| 	// Total rewards for each block is block duration * rewards per second
 | 	// Total rewards for each block is block duration * rewards per second
 | ||||||
|  | |||||||
| @ -89,7 +89,7 @@ func (suite *SupplyIntegrationTests) TestSingleUserAccumulatesRewardsAfterSyncin | |||||||
| 		}) | 		}) | ||||||
| 
 | 
 | ||||||
| 	// User claims all their rewards
 | 	// User claims all their rewards
 | ||||||
| 	suite.NoError(suite.DeliverIncentiveMsg(&msg)) | 	suite.Require().NoError(suite.DeliverIncentiveMsg(&msg)) | ||||||
| 
 | 
 | ||||||
| 	// The users has always had 100% of deposits, so they should receive all rewards for the previous two blocks.
 | 	// The users has always had 100% of deposits, so they should receive all rewards for the previous two blocks.
 | ||||||
| 	// Total rewards for each block is block duration * rewards per second
 | 	// Total rewards for each block is block duration * rewards per second
 | ||||||
|  | |||||||
| @ -94,7 +94,7 @@ func (suite *USDXIntegrationTests) TestSingleUserAccumulatesRewardsAfterSyncing( | |||||||
| 
 | 
 | ||||||
| 	// User claims all their rewards
 | 	// User claims all their rewards
 | ||||||
| 	msg := types.NewMsgClaimUSDXMintingReward(userA.String(), "large") | 	msg := types.NewMsgClaimUSDXMintingReward(userA.String(), "large") | ||||||
| 	suite.NoError(suite.DeliverIncentiveMsg(&msg)) | 	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.
 | 	// 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
 | 	// Total rewards for each block is block duration * rewards per second
 | ||||||
| @ -141,7 +141,7 @@ func (suite *USDXIntegrationTests) TestSingleUserAccumulatesRewardsWithoutSyncin | |||||||
| 	suite.NextBlockAfter(1e6 * time.Second) | 	suite.NextBlockAfter(1e6 * time.Second) | ||||||
| 
 | 
 | ||||||
| 	msg := types.NewMsgClaimUSDXMintingReward(user.String(), "large") | 	msg := types.NewMsgClaimUSDXMintingReward(user.String(), "large") | ||||||
| 	suite.NoError(suite.DeliverIncentiveMsg(&msg)) | 	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.
 | 	// 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
 | 	// Total rewards for each block is block duration * rewards per second
 | ||||||
| @ -217,7 +217,7 @@ func (suite *USDXIntegrationTests) TestReinstatingRewardParamsDoesNotTriggerOver | |||||||
| 
 | 
 | ||||||
| 	// Claim rewards
 | 	// Claim rewards
 | ||||||
| 	msg := types.NewMsgClaimUSDXMintingReward(userB.String(), "large") | 	msg := types.NewMsgClaimUSDXMintingReward(userB.String(), "large") | ||||||
| 	suite.NoError(suite.DeliverIncentiveMsg(&msg)) | 	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
 | 	// The cdp had half the total borrows for a 1s block. So should earn half the rewards for that block
 | ||||||
| 	suite.BalanceInEpsilon( | 	suite.BalanceInEpsilon( | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 drklee3
						drklee3