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

     1  package keeper_test
     2  
     3  import (
     4  	"fmt"
     5  	"testing"
     6  
     7  	"github.com/stretchr/testify/require"
     8  
     9  	"cosmossdk.io/collections"
    10  	sdkmath "cosmossdk.io/math"
    11  
    12  	"github.com/cosmos/cosmos-sdk/codec/address"
    13  	simtestutil "github.com/cosmos/cosmos-sdk/testutil/sims"
    14  	sdk "github.com/cosmos/cosmos-sdk/types"
    15  	authtypes "github.com/cosmos/cosmos-sdk/x/auth/types"
    16  	disttypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
    17  	v1 "github.com/cosmos/cosmos-sdk/x/gov/types/v1"
    18  )
    19  
    20  const (
    21  	baseDepositTestAmount  = 100
    22  	baseDepositTestPercent = 25
    23  )
    24  
    25  func TestDeposits(t *testing.T) {
    26  	testcases := []struct {
    27  		name      string
    28  		expedited bool
    29  	}{
    30  		{
    31  			name: "regular",
    32  		},
    33  		{
    34  			name:      "expedited",
    35  			expedited: true,
    36  		},
    37  	}
    38  
    39  	for _, tc := range testcases {
    40  		t.Run(tc.name, func(t *testing.T) {
    41  			govKeeper, authKeeper, bankKeeper, stakingKeeper, distKeeper, _, ctx := setupGovKeeper(t)
    42  			trackMockBalances(bankKeeper, distKeeper)
    43  
    44  			// With expedited proposals the minimum deposit is higher, so we must
    45  			// initialize and deposit an amount depositMultiplier times larger
    46  			// than the regular min deposit amount.
    47  			depositMultiplier := int64(1)
    48  			if tc.expedited {
    49  				depositMultiplier = v1.DefaultMinExpeditedDepositTokensRatio
    50  			}
    51  
    52  			TestAddrs := simtestutil.AddTestAddrsIncremental(bankKeeper, stakingKeeper, ctx, 2, sdkmath.NewInt(10000000*depositMultiplier))
    53  			authKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes()
    54  
    55  			tp := TestProposal
    56  			proposal, err := govKeeper.SubmitProposal(ctx, tp, "", "title", "summary", TestAddrs[0], tc.expedited)
    57  			require.NoError(t, err)
    58  			proposalID := proposal.Id
    59  
    60  			fourStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, stakingKeeper.TokensFromConsensusPower(ctx, 4*depositMultiplier)))
    61  			fiveStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, stakingKeeper.TokensFromConsensusPower(ctx, 5*depositMultiplier)))
    62  
    63  			addr0Initial := bankKeeper.GetAllBalances(ctx, TestAddrs[0])
    64  			addr1Initial := bankKeeper.GetAllBalances(ctx, TestAddrs[1])
    65  
    66  			require.True(t, sdk.NewCoins(proposal.TotalDeposit...).Equal(sdk.NewCoins()))
    67  
    68  			// Check no deposits at beginning
    69  			_, err = govKeeper.Deposits.Get(ctx, collections.Join(proposalID, TestAddrs[1]))
    70  			require.ErrorIs(t, err, collections.ErrNotFound)
    71  			proposal, err = govKeeper.Proposals.Get(ctx, proposalID)
    72  			require.Nil(t, err)
    73  			require.Nil(t, proposal.VotingStartTime)
    74  
    75  			// Check first deposit
    76  			votingStarted, err := govKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fourStake)
    77  			require.NoError(t, err)
    78  			require.False(t, votingStarted)
    79  			deposit, err := govKeeper.Deposits.Get(ctx, collections.Join(proposalID, TestAddrs[0]))
    80  			require.Nil(t, err)
    81  			require.Equal(t, fourStake, sdk.NewCoins(deposit.Amount...))
    82  			require.Equal(t, TestAddrs[0].String(), deposit.Depositor)
    83  			proposal, err = govKeeper.Proposals.Get(ctx, proposalID)
    84  			require.Nil(t, err)
    85  			require.Equal(t, fourStake, sdk.NewCoins(proposal.TotalDeposit...))
    86  			require.Equal(t, addr0Initial.Sub(fourStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[0]))
    87  
    88  			// Check a second deposit from same address
    89  			votingStarted, err = govKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fiveStake)
    90  			require.NoError(t, err)
    91  			require.False(t, votingStarted)
    92  			deposit, err = govKeeper.Deposits.Get(ctx, collections.Join(proposalID, TestAddrs[0]))
    93  			require.Nil(t, err)
    94  			require.Equal(t, fourStake.Add(fiveStake...), sdk.NewCoins(deposit.Amount...))
    95  			require.Equal(t, TestAddrs[0].String(), deposit.Depositor)
    96  			proposal, err = govKeeper.Proposals.Get(ctx, proposalID)
    97  			require.Nil(t, err)
    98  			require.Equal(t, fourStake.Add(fiveStake...), sdk.NewCoins(proposal.TotalDeposit...))
    99  			require.Equal(t, addr0Initial.Sub(fourStake...).Sub(fiveStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[0]))
   100  
   101  			// Check third deposit from a new address
   102  			votingStarted, err = govKeeper.AddDeposit(ctx, proposalID, TestAddrs[1], fourStake)
   103  			require.NoError(t, err)
   104  			require.True(t, votingStarted)
   105  			deposit, err = govKeeper.Deposits.Get(ctx, collections.Join(proposalID, TestAddrs[1]))
   106  			require.Nil(t, err)
   107  			require.Equal(t, TestAddrs[1].String(), deposit.Depositor)
   108  			require.Equal(t, fourStake, sdk.NewCoins(deposit.Amount...))
   109  			proposal, err = govKeeper.Proposals.Get(ctx, proposalID)
   110  			require.Nil(t, err)
   111  			require.Equal(t, fourStake.Add(fiveStake...).Add(fourStake...), sdk.NewCoins(proposal.TotalDeposit...))
   112  			require.Equal(t, addr1Initial.Sub(fourStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[1]))
   113  
   114  			// Check that proposal moved to voting period
   115  			proposal, err = govKeeper.Proposals.Get(ctx, proposalID)
   116  			require.Nil(t, err)
   117  			require.True(t, proposal.VotingStartTime.Equal(ctx.BlockHeader().Time))
   118  
   119  			// Test deposit iterator
   120  			// NOTE order of deposits is determined by the addresses
   121  			var deposits v1.Deposits
   122  			err = govKeeper.Deposits.Walk(ctx, nil, func(_ collections.Pair[uint64, sdk.AccAddress], deposit v1.Deposit) (bool, error) {
   123  				deposits = append(deposits, &deposit)
   124  				return false, nil
   125  			})
   126  			require.NoError(t, err)
   127  			require.Len(t, deposits, 2)
   128  			propDeposits, _ := govKeeper.GetDeposits(ctx, proposalID)
   129  			require.Equal(t, deposits, propDeposits)
   130  			require.Equal(t, TestAddrs[0].String(), deposits[0].Depositor)
   131  			require.Equal(t, fourStake.Add(fiveStake...), sdk.NewCoins(deposits[0].Amount...))
   132  			require.Equal(t, TestAddrs[1].String(), deposits[1].Depositor)
   133  			require.Equal(t, fourStake, sdk.NewCoins(deposits[1].Amount...))
   134  
   135  			// Test Refund Deposits
   136  			deposit, err = govKeeper.Deposits.Get(ctx, collections.Join(proposalID, TestAddrs[1]))
   137  			require.Nil(t, err)
   138  			require.Equal(t, fourStake, sdk.NewCoins(deposit.Amount...))
   139  			govKeeper.RefundAndDeleteDeposits(ctx, proposalID)
   140  			deposit, err = govKeeper.Deposits.Get(ctx, collections.Join(proposalID, TestAddrs[1]))
   141  			require.ErrorIs(t, err, collections.ErrNotFound)
   142  			require.Equal(t, addr0Initial, bankKeeper.GetAllBalances(ctx, TestAddrs[0]))
   143  			require.Equal(t, addr1Initial, bankKeeper.GetAllBalances(ctx, TestAddrs[1]))
   144  
   145  			// Test delete and burn deposits
   146  			proposal, err = govKeeper.SubmitProposal(ctx, tp, "", "title", "summary", TestAddrs[0], true)
   147  			require.NoError(t, err)
   148  			proposalID = proposal.Id
   149  			_, err = govKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fourStake)
   150  			require.NoError(t, err)
   151  			govKeeper.DeleteAndBurnDeposits(ctx, proposalID)
   152  			deposits, _ = govKeeper.GetDeposits(ctx, proposalID)
   153  			require.Len(t, deposits, 0)
   154  			require.Equal(t, addr0Initial.Sub(fourStake...), bankKeeper.GetAllBalances(ctx, TestAddrs[0]))
   155  		})
   156  	}
   157  }
   158  
   159  func TestDepositAmount(t *testing.T) {
   160  	testcases := []struct {
   161  		name            string
   162  		deposit         sdk.Coins
   163  		minDepositRatio string
   164  		err             string
   165  	}{
   166  		{
   167  			name:            "good amount and denoms",
   168  			deposit:         sdk.NewCoins(sdk.NewInt64Coin("stake", 10000)),
   169  			minDepositRatio: "0.001",
   170  		},
   171  		{
   172  			name:            "good amount and denoms but not enough balance for zcoin",
   173  			deposit:         sdk.NewCoins(sdk.NewInt64Coin("stake", 10000), sdk.NewInt64Coin("zcoin", 1)),
   174  			minDepositRatio: "0.001",
   175  			err:             "not enough balance",
   176  		},
   177  		{
   178  			name:            "too small amount",
   179  			deposit:         sdk.NewCoins(sdk.NewInt64Coin("stake", 10)),
   180  			minDepositRatio: "0.001",
   181  			err:             "received 10stake but need at least one of the following: 10000stake,10zcoin: minimum deposit is too small",
   182  		},
   183  		{
   184  			name:            "too small amount with another coin",
   185  			deposit:         sdk.NewCoins(sdk.NewInt64Coin("zcoin", 1)),
   186  			minDepositRatio: "0.001",
   187  			err:             "received 1zcoin but need at least one of the following: 10000stake,10zcoin: minimum deposit is too small",
   188  		},
   189  		{
   190  			name:            "bad denom",
   191  			deposit:         sdk.NewCoins(sdk.NewInt64Coin("euro", 10000)),
   192  			minDepositRatio: "0.001",
   193  			err:             "deposited 10000euro, but gov accepts only the following denom(s): [stake zcoin]: invalid deposit denom",
   194  		},
   195  		{
   196  			name:            "mix containing bad and good denom",
   197  			deposit:         sdk.NewCoins(sdk.NewInt64Coin("stake", 10000), sdk.NewInt64Coin("euro", 10000)),
   198  			minDepositRatio: "0.001",
   199  			err:             "deposited 10000euro,10000stake, but gov accepts only the following denom(s): [stake zcoin]: invalid deposit denom",
   200  		},
   201  		{
   202  			name:            "minDepositRatio is zero",
   203  			deposit:         sdk.NewCoins(sdk.NewInt64Coin("stake", 10)),
   204  			minDepositRatio: "0.0",
   205  		},
   206  	}
   207  
   208  	for _, tc := range testcases {
   209  		t.Run(tc.name, func(t *testing.T) {
   210  			govKeeper, authKeeper, bankKeeper, stakingKeeper, distrKeeper, _, ctx := setupGovKeeper(t)
   211  			trackMockBalances(bankKeeper, distrKeeper)
   212  
   213  			testAddrs := simtestutil.AddTestAddrsIncremental(bankKeeper, stakingKeeper, ctx, 2, sdkmath.NewInt(1000000000000000))
   214  			authKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes()
   215  
   216  			params, _ := govKeeper.Params.Get(ctx)
   217  			params.MinDepositRatio = tc.minDepositRatio
   218  			params.MinDeposit = sdk.NewCoins(params.MinDeposit...).Add(sdk.NewCoin("zcoin", sdkmath.NewInt(10000))) // coins must be sorted by denom
   219  			err := govKeeper.Params.Set(ctx, params)
   220  			require.NoError(t, err)
   221  
   222  			tp := TestProposal
   223  			proposal, err := govKeeper.SubmitProposal(ctx, tp, "", "title", "summary", testAddrs[0], false)
   224  			require.NoError(t, err)
   225  			proposalID := proposal.Id
   226  
   227  			_, err = govKeeper.AddDeposit(ctx, proposalID, testAddrs[0], tc.deposit)
   228  			if tc.err != "" {
   229  				require.Error(t, err)
   230  				require.Equal(t, tc.err, err.Error())
   231  			} else {
   232  				require.NoError(t, err)
   233  			}
   234  		})
   235  	}
   236  }
   237  
   238  func TestValidateInitialDeposit(t *testing.T) {
   239  	testcases := map[string]struct {
   240  		minDeposit               sdk.Coins
   241  		minInitialDepositPercent int64
   242  		initialDeposit           sdk.Coins
   243  		expedited                bool
   244  
   245  		expectError bool
   246  	}{
   247  		"min deposit * initial percent == initial deposit: success": {
   248  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   249  			minInitialDepositPercent: baseDepositTestPercent,
   250  			initialDeposit:           sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100))),
   251  		},
   252  		"min deposit * initial percent < initial deposit: success": {
   253  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   254  			minInitialDepositPercent: baseDepositTestPercent,
   255  			initialDeposit:           sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100+1))),
   256  		},
   257  		"min deposit * initial percent > initial deposit: error": {
   258  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   259  			minInitialDepositPercent: baseDepositTestPercent,
   260  			initialDeposit:           sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100-1))),
   261  
   262  			expectError: true,
   263  		},
   264  		"min deposit * initial percent == initial deposit (non-base values and denom): success": {
   265  			minDeposit:               sdk.NewCoins(sdk.NewCoin("uosmo", sdkmath.NewInt(56912))),
   266  			minInitialDepositPercent: 50,
   267  			initialDeposit:           sdk.NewCoins(sdk.NewCoin("uosmo", sdkmath.NewInt(56912/2+10))),
   268  		},
   269  		"min deposit * initial percent == initial deposit but different denoms: error": {
   270  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   271  			minInitialDepositPercent: baseDepositTestPercent,
   272  			initialDeposit:           sdk.NewCoins(sdk.NewCoin("uosmo", sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100))),
   273  
   274  			expectError: true,
   275  		},
   276  		"min deposit * initial percent == initial deposit (multiple coins): success": {
   277  			minDeposit: sdk.NewCoins(
   278  				sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount)),
   279  				sdk.NewCoin("uosmo", sdkmath.NewInt(baseDepositTestAmount*2))),
   280  			minInitialDepositPercent: baseDepositTestPercent,
   281  			initialDeposit: sdk.NewCoins(
   282  				sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100)),
   283  				sdk.NewCoin("uosmo", sdkmath.NewInt(baseDepositTestAmount*2*baseDepositTestPercent/100)),
   284  			),
   285  		},
   286  		"min deposit * initial percent > initial deposit (multiple coins): error": {
   287  			minDeposit: sdk.NewCoins(
   288  				sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount)),
   289  				sdk.NewCoin("uosmo", sdkmath.NewInt(baseDepositTestAmount*2))),
   290  			minInitialDepositPercent: baseDepositTestPercent,
   291  			initialDeposit: sdk.NewCoins(
   292  				sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100)),
   293  				sdk.NewCoin("uosmo", sdkmath.NewInt(baseDepositTestAmount*2*baseDepositTestPercent/100-1)),
   294  			),
   295  
   296  			expectError: true,
   297  		},
   298  		"min deposit * initial percent < initial deposit (multiple coins - coin not required by min deposit): success": {
   299  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   300  			minInitialDepositPercent: baseDepositTestPercent,
   301  			initialDeposit: sdk.NewCoins(
   302  				sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100)),
   303  				sdk.NewCoin("uosmo", sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100-1)),
   304  			),
   305  		},
   306  		"0 initial percent: success": {
   307  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   308  			minInitialDepositPercent: 0,
   309  			initialDeposit:           sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100))),
   310  		},
   311  		"expedited min deposit * initial percent == initial deposit: success": {
   312  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   313  			minInitialDepositPercent: baseDepositTestPercent,
   314  			initialDeposit:           sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100))),
   315  			expedited:                true,
   316  		},
   317  		"expedited - 0 initial percent: success": {
   318  			minDeposit:               sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount))),
   319  			minInitialDepositPercent: 0,
   320  			initialDeposit:           sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, sdkmath.NewInt(baseDepositTestAmount*baseDepositTestPercent/100))),
   321  			expedited:                true,
   322  		},
   323  	}
   324  
   325  	for name, tc := range testcases {
   326  		t.Run(name, func(t *testing.T) {
   327  			govKeeper, _, _, _, _, _, ctx := setupGovKeeper(t)
   328  
   329  			params := v1.DefaultParams()
   330  			if tc.expedited {
   331  				params.ExpeditedMinDeposit = tc.minDeposit
   332  			} else {
   333  				params.MinDeposit = tc.minDeposit
   334  			}
   335  			params.MinInitialDepositRatio = sdkmath.LegacyNewDec(tc.minInitialDepositPercent).Quo(sdkmath.LegacyNewDec(100)).String()
   336  
   337  			govKeeper.Params.Set(ctx, params)
   338  
   339  			err := govKeeper.ValidateInitialDeposit(ctx, tc.initialDeposit, tc.expedited)
   340  
   341  			if tc.expectError {
   342  				require.Error(t, err)
   343  				return
   344  			}
   345  			require.NoError(t, err)
   346  		})
   347  	}
   348  }
   349  
   350  func TestChargeDeposit(t *testing.T) {
   351  	testCases := []struct {
   352  		name                      string
   353  		proposalCancelRatio       string
   354  		proposalCancelDestAddress string
   355  		expectError               bool
   356  	}{
   357  		{
   358  			name:                      "Success: CancelRatio=0",
   359  			proposalCancelRatio:       "0",
   360  			proposalCancelDestAddress: "",
   361  			expectError:               false,
   362  		},
   363  		{
   364  			name:                      "Success: CancelRatio=0.5",
   365  			proposalCancelRatio:       "0.5",
   366  			proposalCancelDestAddress: "",
   367  			expectError:               false,
   368  		},
   369  		{
   370  			name:                      "Success: CancelRatio=1",
   371  			proposalCancelRatio:       "1",
   372  			proposalCancelDestAddress: "",
   373  			expectError:               false,
   374  		},
   375  	}
   376  
   377  	for _, tc := range testCases {
   378  		for i := 0; i < 3; i++ {
   379  			testName := func(i int) string {
   380  				if i == 0 {
   381  					return fmt.Sprintf("%s and dest address is %s", tc.name, "nil")
   382  				} else if i == 1 {
   383  					return fmt.Sprintf("%s and dest address is normal address", tc.name)
   384  				}
   385  				return fmt.Sprintf("%s and dest address is community address", tc.name)
   386  			}
   387  
   388  			t.Run(testName(i), func(t *testing.T) {
   389  				govKeeper, authKeeper, bankKeeper, stakingKeeper, _, _, ctx := setupGovKeeper(t)
   390  				params := v1.DefaultParams()
   391  				params.ProposalCancelRatio = tc.proposalCancelRatio
   392  				TestAddrs := simtestutil.AddTestAddrsIncremental(bankKeeper, stakingKeeper, ctx, 2, sdkmath.NewInt(10000000000))
   393  				authKeeper.EXPECT().AddressCodec().Return(address.NewBech32Codec("cosmos")).AnyTimes()
   394  
   395  				switch i {
   396  				case 0:
   397  					// no dest address for cancel proposal, total cancellation charges will be burned
   398  					params.ProposalCancelDest = ""
   399  				case 1:
   400  					// normal account address for proposal cancel dest address
   401  					params.ProposalCancelDest = TestAddrs[1].String()
   402  				default:
   403  					// community address for proposal cancel dest address
   404  					params.ProposalCancelDest = authtypes.NewModuleAddress(disttypes.ModuleName).String()
   405  				}
   406  
   407  				err := govKeeper.Params.Set(ctx, params)
   408  				require.NoError(t, err)
   409  
   410  				tp := TestProposal
   411  				proposal, err := govKeeper.SubmitProposal(ctx, tp, "", "title", "summary", TestAddrs[0], false)
   412  				require.NoError(t, err)
   413  				proposalID := proposal.Id
   414  				// deposit to proposal
   415  				fiveStake := sdk.NewCoins(sdk.NewCoin(sdk.DefaultBondDenom, stakingKeeper.TokensFromConsensusPower(ctx, 300)))
   416  				_, err = govKeeper.AddDeposit(ctx, proposalID, TestAddrs[0], fiveStake)
   417  				require.NoError(t, err)
   418  
   419  				codec := address.NewBech32Codec("cosmos")
   420  				// get balances of dest address
   421  				var prevBalance sdk.Coin
   422  				if len(params.ProposalCancelDest) != 0 {
   423  					accAddr, err := codec.StringToBytes(params.ProposalCancelDest)
   424  					require.NoError(t, err)
   425  					prevBalance = bankKeeper.GetBalance(ctx, accAddr, sdk.DefaultBondDenom)
   426  				}
   427  
   428  				// get the deposits
   429  				allDeposits, _ := govKeeper.GetDeposits(ctx, proposalID)
   430  
   431  				// charge cancellation charges for cancel proposal
   432  				err = govKeeper.ChargeDeposit(ctx, proposalID, TestAddrs[0].String(), params.ProposalCancelRatio)
   433  				if tc.expectError {
   434  					require.Error(t, err)
   435  					return
   436  				}
   437  				require.NoError(t, err)
   438  
   439  				if len(params.ProposalCancelDest) != 0 {
   440  					accAddr, err := codec.StringToBytes(params.ProposalCancelDest)
   441  					require.NoError(t, err)
   442  					newBalanceAfterCancelProposal := bankKeeper.GetBalance(ctx, accAddr, sdk.DefaultBondDenom)
   443  					cancellationCharges := sdkmath.NewInt(0)
   444  					for _, deposits := range allDeposits {
   445  						for _, deposit := range deposits.Amount {
   446  							burnAmount := sdkmath.LegacyNewDecFromInt(deposit.Amount).Mul(sdkmath.LegacyMustNewDecFromStr(params.MinInitialDepositRatio)).TruncateInt()
   447  							cancellationCharges = cancellationCharges.Add(burnAmount)
   448  						}
   449  					}
   450  					require.True(t, newBalanceAfterCancelProposal.Equal(prevBalance.Add(sdk.NewCoin(sdk.DefaultBondDenom, cancellationCharges))))
   451  				}
   452  			})
   453  		}
   454  	}
   455  }