github.com/cosmos/cosmos-sdk@v0.50.10/x/distribution/keeper/keeper_test.go (about)

     1  package keeper_test
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	cmtproto "github.com/cometbft/cometbft/proto/tendermint/types"
     8  	"github.com/golang/mock/gomock"
     9  	"github.com/stretchr/testify/require"
    10  
    11  	"cosmossdk.io/math"
    12  	storetypes "cosmossdk.io/store/types"
    13  
    14  	"github.com/cosmos/cosmos-sdk/runtime"
    15  	"github.com/cosmos/cosmos-sdk/testutil"
    16  	simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
    17  	sdk "github.com/cosmos/cosmos-sdk/types"
    18  	moduletestutil "github.com/cosmos/cosmos-sdk/types/module/testutil"
    19  	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    20  	"github.com/cosmos/cosmos-sdk/x/distribution"
    21  	"github.com/cosmos/cosmos-sdk/x/distribution/keeper"
    22  	distrtestutil "github.com/cosmos/cosmos-sdk/x/distribution/testutil"
    23  	"github.com/cosmos/cosmos-sdk/x/distribution/types"
    24  )
    25  
    26  func TestSetWithdrawAddr(t *testing.T) {
    27  	ctrl := gomock.NewController(t)
    28  	key := storetypes.NewKVStoreKey(types.StoreKey)
    29  	storeService := runtime.NewKVStoreService(key)
    30  	testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
    31  	encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{})
    32  	ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()})
    33  	addrs := simtestutil.CreateIncrementalAccounts(2)
    34  
    35  	delegatorAddr := addrs[0]
    36  	withdrawAddr := addrs[1]
    37  
    38  	bankKeeper := distrtestutil.NewMockBankKeeper(ctrl)
    39  	stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl)
    40  	accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl)
    41  
    42  	accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress())
    43  
    44  	bankKeeper.EXPECT().BlockedAddr(withdrawAddr).Return(false).AnyTimes()
    45  	bankKeeper.EXPECT().BlockedAddr(distrAcc.GetAddress()).Return(true).AnyTimes()
    46  
    47  	distrKeeper := keeper.NewKeeper(
    48  		encCfg.Codec,
    49  		storeService,
    50  		accountKeeper,
    51  		bankKeeper,
    52  		stakingKeeper,
    53  		"fee_collector",
    54  		authtypes.NewModuleAddress("gov").String(),
    55  	)
    56  
    57  	params := types.DefaultParams()
    58  	params.WithdrawAddrEnabled = false
    59  	require.NoError(t, distrKeeper.Params.Set(ctx, params))
    60  
    61  	err := distrKeeper.SetWithdrawAddr(ctx, delegatorAddr, withdrawAddr)
    62  	require.NotNil(t, err)
    63  
    64  	params.WithdrawAddrEnabled = true
    65  	require.NoError(t, distrKeeper.Params.Set(ctx, params))
    66  
    67  	err = distrKeeper.SetWithdrawAddr(ctx, delegatorAddr, withdrawAddr)
    68  	require.Nil(t, err)
    69  
    70  	require.Error(t, distrKeeper.SetWithdrawAddr(ctx, delegatorAddr, distrAcc.GetAddress()))
    71  }
    72  
    73  func TestWithdrawValidatorCommission(t *testing.T) {
    74  	ctrl := gomock.NewController(t)
    75  	key := storetypes.NewKVStoreKey(types.StoreKey)
    76  	storeService := runtime.NewKVStoreService(key)
    77  	testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
    78  	encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{})
    79  	ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()})
    80  	addrs := simtestutil.CreateIncrementalAccounts(1)
    81  
    82  	valAddr := sdk.ValAddress(addrs[0])
    83  
    84  	bankKeeper := distrtestutil.NewMockBankKeeper(ctrl)
    85  	stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl)
    86  	accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl)
    87  
    88  	accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress())
    89  
    90  	valCommission := sdk.DecCoins{
    91  		sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))),
    92  		sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))),
    93  	}
    94  
    95  	distrKeeper := keeper.NewKeeper(
    96  		encCfg.Codec,
    97  		storeService,
    98  		accountKeeper,
    99  		bankKeeper,
   100  		stakingKeeper,
   101  		"fee_collector",
   102  		authtypes.NewModuleAddress("gov").String(),
   103  	)
   104  
   105  	// set outstanding rewards
   106  	require.NoError(t, distrKeeper.SetValidatorOutstandingRewards(ctx, valAddr, types.ValidatorOutstandingRewards{Rewards: valCommission}))
   107  
   108  	// set commission
   109  	require.NoError(t, distrKeeper.SetValidatorAccumulatedCommission(ctx, valAddr, types.ValidatorAccumulatedCommission{Commission: valCommission}))
   110  
   111  	// withdraw commission
   112  	coins := sdk.NewCoins(sdk.NewCoin("mytoken", math.NewInt(1)), sdk.NewCoin("stake", math.NewInt(1)))
   113  	// if SendCoinsFromModuleToAccount is called, we know that the withdraw was successful
   114  	bankKeeper.EXPECT().SendCoinsFromModuleToAccount(gomock.Any(), "distribution", addrs[0], coins).Return(nil)
   115  
   116  	_, err := distrKeeper.WithdrawValidatorCommission(ctx, valAddr)
   117  	require.NoError(t, err)
   118  
   119  	// check remainder
   120  	remainderValCommission, err := distrKeeper.GetValidatorAccumulatedCommission(ctx, valAddr)
   121  	require.NoError(t, err)
   122  	remainder := remainderValCommission.Commission
   123  	require.Equal(t, sdk.DecCoins{
   124  		sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(1).Quo(math.LegacyNewDec(4))),
   125  		sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(1).Quo(math.LegacyNewDec(2))),
   126  	}, remainder)
   127  }
   128  
   129  func TestGetTotalRewards(t *testing.T) {
   130  	ctrl := gomock.NewController(t)
   131  	key := storetypes.NewKVStoreKey(types.StoreKey)
   132  	storeService := runtime.NewKVStoreService(key)
   133  	testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
   134  	encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{})
   135  	ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()})
   136  	addrs := simtestutil.CreateIncrementalAccounts(2)
   137  
   138  	valAddr0 := sdk.ValAddress(addrs[0])
   139  	valAddr1 := sdk.ValAddress(addrs[1])
   140  
   141  	bankKeeper := distrtestutil.NewMockBankKeeper(ctrl)
   142  	stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl)
   143  	accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl)
   144  
   145  	accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress())
   146  
   147  	distrKeeper := keeper.NewKeeper(
   148  		encCfg.Codec,
   149  		storeService,
   150  		accountKeeper,
   151  		bankKeeper,
   152  		stakingKeeper,
   153  		"fee_collector",
   154  		authtypes.NewModuleAddress("gov").String(),
   155  	)
   156  
   157  	valCommission := sdk.DecCoins{
   158  		sdk.NewDecCoinFromDec("mytoken", math.LegacyNewDec(5).Quo(math.LegacyNewDec(4))),
   159  		sdk.NewDecCoinFromDec("stake", math.LegacyNewDec(3).Quo(math.LegacyNewDec(2))),
   160  	}
   161  
   162  	require.NoError(t, distrKeeper.SetValidatorOutstandingRewards(ctx, valAddr0, types.ValidatorOutstandingRewards{Rewards: valCommission}))
   163  	require.NoError(t, distrKeeper.SetValidatorOutstandingRewards(ctx, valAddr1, types.ValidatorOutstandingRewards{Rewards: valCommission}))
   164  
   165  	expectedRewards := valCommission.MulDec(math.LegacyNewDec(2))
   166  	totalRewards := distrKeeper.GetTotalRewards(ctx)
   167  
   168  	require.Equal(t, expectedRewards, totalRewards)
   169  }
   170  
   171  func TestFundCommunityPool(t *testing.T) {
   172  	ctrl := gomock.NewController(t)
   173  	key := storetypes.NewKVStoreKey(types.StoreKey)
   174  	storeService := runtime.NewKVStoreService(key)
   175  	testCtx := testutil.DefaultContextWithDB(t, key, storetypes.NewTransientStoreKey("transient_test"))
   176  	encCfg := moduletestutil.MakeTestEncodingConfig(distribution.AppModuleBasic{})
   177  	ctx := testCtx.Ctx.WithBlockHeader(cmtproto.Header{Time: time.Now()})
   178  	addrs := simtestutil.CreateIncrementalAccounts(1)
   179  
   180  	bankKeeper := distrtestutil.NewMockBankKeeper(ctrl)
   181  	stakingKeeper := distrtestutil.NewMockStakingKeeper(ctrl)
   182  	accountKeeper := distrtestutil.NewMockAccountKeeper(ctrl)
   183  
   184  	accountKeeper.EXPECT().GetModuleAddress("distribution").Return(distrAcc.GetAddress())
   185  
   186  	distrKeeper := keeper.NewKeeper(
   187  		encCfg.Codec,
   188  		storeService,
   189  		accountKeeper,
   190  		bankKeeper,
   191  		stakingKeeper,
   192  		"fee_collector",
   193  		authtypes.NewModuleAddress("gov").String(),
   194  	)
   195  
   196  	// reset fee pool
   197  	require.NoError(t, distrKeeper.FeePool.Set(ctx, types.InitialFeePool()))
   198  
   199  	initPool, err := distrKeeper.FeePool.Get(ctx)
   200  	require.NoError(t, err)
   201  	require.Empty(t, initPool.CommunityPool)
   202  
   203  	amount := sdk.NewCoins(sdk.NewInt64Coin("stake", 100))
   204  	bankKeeper.EXPECT().SendCoinsFromAccountToModule(gomock.Any(), addrs[0], "distribution", amount).Return(nil)
   205  	err = distrKeeper.FundCommunityPool(ctx, amount, addrs[0])
   206  	require.NoError(t, err)
   207  
   208  	feePool, err := distrKeeper.FeePool.Get(ctx)
   209  	require.NoError(t, err)
   210  	require.Equal(t, initPool.CommunityPool.Add(sdk.NewDecCoinsFromCoins(amount...)...), feePool.CommunityPool)
   211  }