github.com/fibonacci-chain/fbc@v0.0.0-20231124064014-c7636198c1e9/x/wasm/keeper/staking_test.go (about)

     1  package keeper
     2  
     3  //import (
     4  //	"encoding/json"
     5  //	"io/ioutil"
     6  //	"testing"
     7  //
     8  //	wasmvmtypes "github.com/CosmWasm/wasmvm/types"
     9  //	codectypes "github.com/cosmos/cosmos-sdk/codec/types"
    10  //	"github.com/cosmos/cosmos-sdk/crypto/keys/secp256k1"
    11  //	sdk "github.com/cosmos/cosmos-sdk/types"
    12  //	authkeeper "github.com/cosmos/cosmos-sdk/x/auth/keeper"
    13  //	bankkeeper "github.com/cosmos/cosmos-sdk/x/bank/keeper"
    14  //	distributionkeeper "github.com/cosmos/cosmos-sdk/x/distribution/keeper"
    15  //	distributiontypes "github.com/cosmos/cosmos-sdk/x/distribution/types"
    16  //	"github.com/cosmos/cosmos-sdk/x/staking"
    17  //	stakingkeeper "github.com/cosmos/cosmos-sdk/x/staking/keeper"
    18  //	"github.com/cosmos/cosmos-sdk/x/staking/types"
    19  //	stakingtypes "github.com/cosmos/cosmos-sdk/x/staking/types"
    20  //	"github.com/stretchr/testify/assert"
    21  //	"github.com/stretchr/testify/require"
    22  //
    23  //	"github.com/CosmWasm/wasmd/x/wasm/keeper/testdata"
    24  //	wasmtypes "github.com/CosmWasm/wasmd/x/wasm/types"
    25  //)
    26  //
    27  //type StakingInitMsg struct {
    28  //	Name      string         `json:"name"`
    29  //	Symbol    string         `json:"symbol"`
    30  //	Decimals  uint8          `json:"decimals"`
    31  //	Validator sdk.ValAddress `json:"validator"`
    32  //	ExitTax   sdk.Dec        `json:"exit_tax"`
    33  //	// MinWithdrawal is uint128 encoded as a string (use sdk.Int?)
    34  //	MinWithdrawl string `json:"min_withdrawal"`
    35  //}
    36  //
    37  //// StakingHandleMsg is used to encode handle messages
    38  //type StakingHandleMsg struct {
    39  //	Transfer *transferPayload       `json:"transfer,omitempty"`
    40  //	Bond     *struct{}              `json:"bond,omitempty"`
    41  //	Unbond   *unbondPayload         `json:"unbond,omitempty"`
    42  //	Claim    *struct{}              `json:"claim,omitempty"`
    43  //	Reinvest *struct{}              `json:"reinvest,omitempty"`
    44  //	Change   *testdata.OwnerPayload `json:"change_owner,omitempty"`
    45  //}
    46  //
    47  //type transferPayload struct {
    48  //	Recipient sdk.Address `json:"recipient"`
    49  //	// uint128 encoded as string
    50  //	Amount string `json:"amount"`
    51  //}
    52  //
    53  //type unbondPayload struct {
    54  //	// uint128 encoded as string
    55  //	Amount string `json:"amount"`
    56  //}
    57  //
    58  //// StakingQueryMsg is used to encode query messages
    59  //type StakingQueryMsg struct {
    60  //	Balance    *addressQuery `json:"balance,omitempty"`
    61  //	Claims     *addressQuery `json:"claims,omitempty"`
    62  //	TokenInfo  *struct{}     `json:"token_info,omitempty"`
    63  //	Investment *struct{}     `json:"investment,omitempty"`
    64  //}
    65  //
    66  //type addressQuery struct {
    67  //	Address sdk.AccAddress `json:"address"`
    68  //}
    69  //
    70  //type BalanceResponse struct {
    71  //	Balance string `json:"balance,omitempty"`
    72  //}
    73  //
    74  //type ClaimsResponse struct {
    75  //	Claims string `json:"claims,omitempty"`
    76  //}
    77  //
    78  //type TokenInfoResponse struct {
    79  //	Name     string `json:"name"`
    80  //	Symbol   string `json:"symbol"`
    81  //	Decimals uint8  `json:"decimals"`
    82  //}
    83  //
    84  //type InvestmentResponse struct {
    85  //	TokenSupply  string         `json:"token_supply"`
    86  //	StakedTokens sdk.Coin       `json:"staked_tokens"`
    87  //	NominalValue sdk.Dec        `json:"nominal_value"`
    88  //	Owner        sdk.AccAddress `json:"owner"`
    89  //	Validator    sdk.ValAddress `json:"validator"`
    90  //	ExitTax      sdk.Dec        `json:"exit_tax"`
    91  //	// MinWithdrawl is uint128 encoded as a string (use sdk.Int?)
    92  //	MinWithdrawl string `json:"min_withdrawal"`
    93  //}
    94  //
    95  //func TestInitializeStaking(t *testing.T) {
    96  //	ctx, k := CreateTestInput(t, false, SupportedFeatures)
    97  //	accKeeper, stakingKeeper, keeper, bankKeeper := k.AccountKeeper, k.StakingKeeper, k.ContractKeeper, k.BankKeeper
    98  //
    99  //	valAddr := addValidator(t, ctx, stakingKeeper, k.Faucet, sdk.NewInt64Coin("stake", 1234567))
   100  //	ctx = nextBlock(ctx, stakingKeeper)
   101  //	v, found := stakingKeeper.GetValidator(ctx, valAddr)
   102  //	assert.True(t, found)
   103  //	assert.Equal(t, v.GetDelegatorShares(), sdk.NewDec(1234567))
   104  //
   105  //	deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000), sdk.NewInt64Coin("stake", 500000))
   106  //	creator := k.Faucet.NewFundedAccount(ctx, deposit...)
   107  //
   108  //	// upload staking derivates code
   109  //	stakingCode, err := ioutil.ReadFile("./testdata/staking.wasm")
   110  //	require.NoError(t, err)
   111  //	stakingID, err := keeper.Create(ctx, creator, stakingCode, nil)
   112  //	require.NoError(t, err)
   113  //	require.Equal(t, uint64(1), stakingID)
   114  //
   115  //	// register to a valid address
   116  //	initMsg := StakingInitMsg{
   117  //		Name:         "Staking Derivatives",
   118  //		Symbol:       "DRV",
   119  //		Decimals:     0,
   120  //		Validator:    valAddr,
   121  //		ExitTax:      sdk.MustNewDecFromStr("0.10"),
   122  //		MinWithdrawl: "100",
   123  //	}
   124  //	initBz, err := json.Marshal(&initMsg)
   125  //	require.NoError(t, err)
   126  //
   127  //	stakingAddr, _, err := k.ContractKeeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil)
   128  //	require.NoError(t, err)
   129  //	require.NotEmpty(t, stakingAddr)
   130  //
   131  //	// nothing spent here
   132  //	checkAccount(t, ctx, accKeeper, bankKeeper, creator, deposit)
   133  //
   134  //	// try to register with a validator not on the list and it fails
   135  //	_, _, bob := keyPubAddr()
   136  //	badInitMsg := StakingInitMsg{
   137  //		Name:         "Missing Validator",
   138  //		Symbol:       "MISS",
   139  //		Decimals:     0,
   140  //		Validator:    sdk.ValAddress(bob),
   141  //		ExitTax:      sdk.MustNewDecFromStr("0.10"),
   142  //		MinWithdrawl: "100",
   143  //	}
   144  //	badBz, err := json.Marshal(&badInitMsg)
   145  //	require.NoError(t, err)
   146  //
   147  //	_, _, err = k.ContractKeeper.Instantiate(ctx, stakingID, creator, nil, badBz, "missing validator", nil)
   148  //	require.Error(t, err)
   149  //
   150  //	// no changes to bonding shares
   151  //	val, _ := stakingKeeper.GetValidator(ctx, valAddr)
   152  //	assert.Equal(t, val.GetDelegatorShares(), sdk.NewDec(1234567))
   153  //}
   154  //
   155  //type initInfo struct {
   156  //	valAddr      sdk.ValAddress
   157  //	creator      sdk.AccAddress
   158  //	contractAddr sdk.AccAddress
   159  //
   160  //	ctx            sdk.Context
   161  //	accKeeper      authkeeper.AccountKeeper
   162  //	stakingKeeper  stakingkeeper.Keeper
   163  //	distKeeper     distributionkeeper.Keeper
   164  //	wasmKeeper     Keeper
   165  //	contractKeeper wasmtypes.ContractOpsKeeper
   166  //	bankKeeper     bankkeeper.Keeper
   167  //	faucet         *TestFaucet
   168  //}
   169  //
   170  //func initializeStaking(t *testing.T) initInfo {
   171  //	ctx, k := CreateTestInput(t, false, SupportedFeatures)
   172  //	accKeeper, stakingKeeper, keeper, bankKeeper := k.AccountKeeper, k.StakingKeeper, k.WasmKeeper, k.BankKeeper
   173  //
   174  //	valAddr := addValidator(t, ctx, stakingKeeper, k.Faucet, sdk.NewInt64Coin("stake", 1000000))
   175  //	ctx = nextBlock(ctx, stakingKeeper)
   176  //
   177  //	// set some baseline - this seems to be needed
   178  //	k.DistKeeper.SetValidatorHistoricalRewards(ctx, valAddr, 0, distributiontypes.ValidatorHistoricalRewards{
   179  //		CumulativeRewardRatio: sdk.DecCoins{},
   180  //		ReferenceCount:        1,
   181  //	})
   182  //
   183  //	v, found := stakingKeeper.GetValidator(ctx, valAddr)
   184  //	assert.True(t, found)
   185  //	assert.Equal(t, v.GetDelegatorShares(), sdk.NewDec(1000000))
   186  //	assert.Equal(t, v.Status, stakingtypes.Bonded)
   187  //
   188  //	deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000), sdk.NewInt64Coin("stake", 500000))
   189  //	creator := k.Faucet.NewFundedAccount(ctx, deposit...)
   190  //
   191  //	// upload staking derivates code
   192  //	stakingCode, err := ioutil.ReadFile("./testdata/staking.wasm")
   193  //	require.NoError(t, err)
   194  //	stakingID, err := k.ContractKeeper.Create(ctx, creator, stakingCode, nil)
   195  //	require.NoError(t, err)
   196  //	require.Equal(t, uint64(1), stakingID)
   197  //
   198  //	// register to a valid address
   199  //	initMsg := StakingInitMsg{
   200  //		Name:         "Staking Derivatives",
   201  //		Symbol:       "DRV",
   202  //		Decimals:     0,
   203  //		Validator:    valAddr,
   204  //		ExitTax:      sdk.MustNewDecFromStr("0.10"),
   205  //		MinWithdrawl: "100",
   206  //	}
   207  //	initBz, err := json.Marshal(&initMsg)
   208  //	require.NoError(t, err)
   209  //
   210  //	stakingAddr, _, err := k.ContractKeeper.Instantiate(ctx, stakingID, creator, nil, initBz, "staking derivates - DRV", nil)
   211  //	require.NoError(t, err)
   212  //	require.NotEmpty(t, stakingAddr)
   213  //
   214  //	return initInfo{
   215  //		valAddr:        valAddr,
   216  //		creator:        creator,
   217  //		contractAddr:   stakingAddr,
   218  //		ctx:            ctx,
   219  //		accKeeper:      accKeeper,
   220  //		stakingKeeper:  stakingKeeper,
   221  //		wasmKeeper:     *keeper,
   222  //		distKeeper:     k.DistKeeper,
   223  //		bankKeeper:     bankKeeper,
   224  //		contractKeeper: k.ContractKeeper,
   225  //		faucet:         k.Faucet,
   226  //	}
   227  //}
   228  //
   229  //func TestBonding(t *testing.T) {
   230  //	initInfo := initializeStaking(t)
   231  //	ctx, valAddr, contractAddr := initInfo.ctx, initInfo.valAddr, initInfo.contractAddr
   232  //	keeper, stakingKeeper, accKeeper, bankKeeper := initInfo.wasmKeeper, initInfo.stakingKeeper, initInfo.accKeeper, initInfo.bankKeeper
   233  //
   234  //	// initial checks of bonding state
   235  //	val, found := stakingKeeper.GetValidator(ctx, valAddr)
   236  //	require.True(t, found)
   237  //	initPower := val.GetDelegatorShares()
   238  //
   239  //	// bob has 160k, putting 80k into the contract
   240  //	full := sdk.NewCoins(sdk.NewInt64Coin("stake", 160000))
   241  //	funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 80000))
   242  //	bob := initInfo.faucet.NewFundedAccount(ctx, full...)
   243  //
   244  //	// check contract state before
   245  //	assertBalance(t, ctx, keeper, contractAddr, bob, "0")
   246  //	assertClaims(t, ctx, keeper, contractAddr, bob, "0")
   247  //	assertSupply(t, ctx, keeper, contractAddr, "0", sdk.NewInt64Coin("stake", 0))
   248  //
   249  //	bond := StakingHandleMsg{
   250  //		Bond: &struct{}{},
   251  //	}
   252  //	bondBz, err := json.Marshal(bond)
   253  //	require.NoError(t, err)
   254  //	_, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds)
   255  //	require.NoError(t, err)
   256  //
   257  //	// check some account values - the money is on neither account (cuz it is bonded)
   258  //	checkAccount(t, ctx, accKeeper, bankKeeper, contractAddr, sdk.Coins{})
   259  //	checkAccount(t, ctx, accKeeper, bankKeeper, bob, funds)
   260  //
   261  //	// make sure the proper number of tokens have been bonded
   262  //	val, _ = stakingKeeper.GetValidator(ctx, valAddr)
   263  //	finalPower := val.GetDelegatorShares()
   264  //	assert.Equal(t, sdk.NewInt(80000), finalPower.Sub(initPower).TruncateInt())
   265  //
   266  //	// check the delegation itself
   267  //	d, found := stakingKeeper.GetDelegation(ctx, contractAddr, valAddr)
   268  //	require.True(t, found)
   269  //	assert.Equal(t, d.Shares, sdk.MustNewDecFromStr("80000"))
   270  //
   271  //	// check we have the desired balance
   272  //	assertBalance(t, ctx, keeper, contractAddr, bob, "80000")
   273  //	assertClaims(t, ctx, keeper, contractAddr, bob, "0")
   274  //	assertSupply(t, ctx, keeper, contractAddr, "80000", sdk.NewInt64Coin("stake", 80000))
   275  //}
   276  //
   277  //func TestUnbonding(t *testing.T) {
   278  //	initInfo := initializeStaking(t)
   279  //	ctx, valAddr, contractAddr := initInfo.ctx, initInfo.valAddr, initInfo.contractAddr
   280  //	keeper, stakingKeeper, accKeeper, bankKeeper := initInfo.wasmKeeper, initInfo.stakingKeeper, initInfo.accKeeper, initInfo.bankKeeper
   281  //
   282  //	// initial checks of bonding state
   283  //	val, found := stakingKeeper.GetValidator(ctx, valAddr)
   284  //	require.True(t, found)
   285  //	initPower := val.GetDelegatorShares()
   286  //
   287  //	// bob has 160k, putting 80k into the contract
   288  //	full := sdk.NewCoins(sdk.NewInt64Coin("stake", 160000))
   289  //	funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 80000))
   290  //	bob := initInfo.faucet.NewFundedAccount(ctx, full...)
   291  //
   292  //	bond := StakingHandleMsg{
   293  //		Bond: &struct{}{},
   294  //	}
   295  //	bondBz, err := json.Marshal(bond)
   296  //	require.NoError(t, err)
   297  //	_, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds)
   298  //	require.NoError(t, err)
   299  //
   300  //	// update height a bit
   301  //	ctx = nextBlock(ctx, stakingKeeper)
   302  //
   303  //	// now unbond 30k - note that 3k (10%) goes to the owner as a tax, 27k unbonded and available as claims
   304  //	unbond := StakingHandleMsg{
   305  //		Unbond: &unbondPayload{
   306  //			Amount: "30000",
   307  //		},
   308  //	}
   309  //	unbondBz, err := json.Marshal(unbond)
   310  //	require.NoError(t, err)
   311  //	_, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, unbondBz, nil)
   312  //	require.NoError(t, err)
   313  //
   314  //	// check some account values - the money is on neither account (cuz it is bonded)
   315  //	// Note: why is this immediate? just test setup?
   316  //	checkAccount(t, ctx, accKeeper, bankKeeper, contractAddr, sdk.Coins{})
   317  //	checkAccount(t, ctx, accKeeper, bankKeeper, bob, funds)
   318  //
   319  //	// make sure the proper number of tokens have been bonded (80k - 27k = 53k)
   320  //	val, _ = stakingKeeper.GetValidator(ctx, valAddr)
   321  //	finalPower := val.GetDelegatorShares()
   322  //	assert.Equal(t, sdk.NewInt(53000), finalPower.Sub(initPower).TruncateInt(), finalPower.String())
   323  //
   324  //	// check the delegation itself
   325  //	d, found := stakingKeeper.GetDelegation(ctx, contractAddr, valAddr)
   326  //	require.True(t, found)
   327  //	assert.Equal(t, d.Shares, sdk.MustNewDecFromStr("53000"))
   328  //
   329  //	// check there is unbonding in progress
   330  //	un, found := stakingKeeper.GetUnbondingDelegation(ctx, contractAddr, valAddr)
   331  //	require.True(t, found)
   332  //	require.Equal(t, 1, len(un.Entries))
   333  //	assert.Equal(t, "27000", un.Entries[0].Balance.String())
   334  //
   335  //	// check we have the desired balance
   336  //	assertBalance(t, ctx, keeper, contractAddr, bob, "50000")
   337  //	assertBalance(t, ctx, keeper, contractAddr, initInfo.creator, "3000")
   338  //	assertClaims(t, ctx, keeper, contractAddr, bob, "27000")
   339  //	assertSupply(t, ctx, keeper, contractAddr, "53000", sdk.NewInt64Coin("stake", 53000))
   340  //}
   341  //
   342  //func TestReinvest(t *testing.T) {
   343  //	initInfo := initializeStaking(t)
   344  //	ctx, valAddr, contractAddr := initInfo.ctx, initInfo.valAddr, initInfo.contractAddr
   345  //	keeper, stakingKeeper, accKeeper, bankKeeper := initInfo.wasmKeeper, initInfo.stakingKeeper, initInfo.accKeeper, initInfo.bankKeeper
   346  //	distKeeper := initInfo.distKeeper
   347  //
   348  //	// initial checks of bonding state
   349  //	val, found := stakingKeeper.GetValidator(ctx, valAddr)
   350  //	require.True(t, found)
   351  //	initPower := val.GetDelegatorShares()
   352  //	assert.Equal(t, val.Tokens, sdk.NewInt(1000000), "%s", val.Tokens)
   353  //
   354  //	// full is 2x funds, 1x goes to the contract, other stays on his wallet
   355  //	full := sdk.NewCoins(sdk.NewInt64Coin("stake", 400000))
   356  //	funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 200000))
   357  //	bob := initInfo.faucet.NewFundedAccount(ctx, full...)
   358  //
   359  //	// we will stake 200k to a validator with 1M self-bond
   360  //	// this means we should get 1/6 of the rewards
   361  //	bond := StakingHandleMsg{
   362  //		Bond: &struct{}{},
   363  //	}
   364  //	bondBz, err := json.Marshal(bond)
   365  //	require.NoError(t, err)
   366  //	_, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds)
   367  //	require.NoError(t, err)
   368  //
   369  //	// update height a bit to solidify the delegation
   370  //	ctx = nextBlock(ctx, stakingKeeper)
   371  //	// we get 1/6, our share should be 40k minus 10% commission = 36k
   372  //	setValidatorRewards(ctx, stakingKeeper, distKeeper, valAddr, "240000")
   373  //
   374  //	// this should withdraw our outstanding 36k of rewards and reinvest them in the same delegation
   375  //	reinvest := StakingHandleMsg{
   376  //		Reinvest: &struct{}{},
   377  //	}
   378  //	reinvestBz, err := json.Marshal(reinvest)
   379  //	require.NoError(t, err)
   380  //	_, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, reinvestBz, nil)
   381  //	require.NoError(t, err)
   382  //
   383  //	// check some account values - the money is on neither account (cuz it is bonded)
   384  //	// Note: why is this immediate? just test setup?
   385  //	checkAccount(t, ctx, accKeeper, bankKeeper, contractAddr, sdk.Coins{})
   386  //	checkAccount(t, ctx, accKeeper, bankKeeper, bob, funds)
   387  //
   388  //	// check the delegation itself
   389  //	d, found := stakingKeeper.GetDelegation(ctx, contractAddr, valAddr)
   390  //	require.True(t, found)
   391  //	// we started with 200k and added 36k
   392  //	assert.Equal(t, d.Shares, sdk.MustNewDecFromStr("236000"))
   393  //
   394  //	// make sure the proper number of tokens have been bonded (80k + 40k = 120k)
   395  //	val, _ = stakingKeeper.GetValidator(ctx, valAddr)
   396  //	finalPower := val.GetDelegatorShares()
   397  //	assert.Equal(t, sdk.NewInt(236000), finalPower.Sub(initPower).TruncateInt(), finalPower.String())
   398  //
   399  //	// check there is no unbonding in progress
   400  //	un, found := stakingKeeper.GetUnbondingDelegation(ctx, contractAddr, valAddr)
   401  //	assert.False(t, found, "%#v", un)
   402  //
   403  //	// check we have the desired balance
   404  //	assertBalance(t, ctx, keeper, contractAddr, bob, "200000")
   405  //	assertBalance(t, ctx, keeper, contractAddr, initInfo.creator, "0")
   406  //	assertClaims(t, ctx, keeper, contractAddr, bob, "0")
   407  //	assertSupply(t, ctx, keeper, contractAddr, "200000", sdk.NewInt64Coin("stake", 236000))
   408  //}
   409  //
   410  //func TestQueryStakingInfo(t *testing.T) {
   411  //	// STEP 1: take a lot of setup from TestReinvest so we have non-zero info
   412  //	initInfo := initializeStaking(t)
   413  //	ctx, valAddr, contractAddr := initInfo.ctx, initInfo.valAddr, initInfo.contractAddr
   414  //	keeper, stakingKeeper := initInfo.wasmKeeper, initInfo.stakingKeeper
   415  //	distKeeper := initInfo.distKeeper
   416  //
   417  //	// initial checks of bonding state
   418  //	val, found := stakingKeeper.GetValidator(ctx, valAddr)
   419  //	require.True(t, found)
   420  //	assert.Equal(t, sdk.NewInt(1000000), val.Tokens)
   421  //
   422  //	// full is 2x funds, 1x goes to the contract, other stays on his wallet
   423  //	full := sdk.NewCoins(sdk.NewInt64Coin("stake", 400000))
   424  //	funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 200000))
   425  //	bob := initInfo.faucet.NewFundedAccount(ctx, full...)
   426  //
   427  //	// we will stake 200k to a validator with 1M self-bond
   428  //	// this means we should get 1/6 of the rewards
   429  //	bond := StakingHandleMsg{
   430  //		Bond: &struct{}{},
   431  //	}
   432  //	bondBz, err := json.Marshal(bond)
   433  //	require.NoError(t, err)
   434  //	_, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds)
   435  //	require.NoError(t, err)
   436  //
   437  //	// update height a bit to solidify the delegation
   438  //	ctx = nextBlock(ctx, stakingKeeper)
   439  //	// we get 1/6, our share should be 40k minus 10% commission = 36k
   440  //	setValidatorRewards(ctx, stakingKeeper, distKeeper, valAddr, "240000")
   441  //
   442  //	// see what the current rewards are
   443  //	origReward := distKeeper.GetValidatorCurrentRewards(ctx, valAddr)
   444  //
   445  //	// STEP 2: Prepare the mask contract
   446  //	deposit := sdk.NewCoins(sdk.NewInt64Coin("denom", 100000))
   447  //	creator := initInfo.faucet.NewFundedAccount(ctx, deposit...)
   448  //
   449  //	// upload mask code
   450  //	maskID, err := initInfo.contractKeeper.Create(ctx, creator, testdata.ReflectContractWasm(), nil)
   451  //	require.NoError(t, err)
   452  //	require.Equal(t, uint64(2), maskID)
   453  //
   454  //	// creator instantiates a contract and gives it tokens
   455  //	maskAddr, _, err := initInfo.contractKeeper.Instantiate(ctx, maskID, creator, nil, []byte("{}"), "mask contract 2", nil)
   456  //	require.NoError(t, err)
   457  //	require.NotEmpty(t, maskAddr)
   458  //
   459  //	// STEP 3: now, let's reflect some queries.
   460  //	// let's get the bonded denom
   461  //	reflectBondedQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
   462  //		BondedDenom: &struct{}{},
   463  //	}}}}
   464  //	reflectBondedBin := buildReflectQuery(t, &reflectBondedQuery)
   465  //	res, err := keeper.QuerySmart(ctx, maskAddr, reflectBondedBin)
   466  //	require.NoError(t, err)
   467  //	// first we pull out the data from chain response, before parsing the original response
   468  //	var reflectRes testdata.ChainResponse
   469  //	mustParse(t, res, &reflectRes)
   470  //	var bondedRes wasmvmtypes.BondedDenomResponse
   471  //	mustParse(t, reflectRes.Data, &bondedRes)
   472  //	assert.Equal(t, "stake", bondedRes.Denom)
   473  //
   474  //	// now, let's reflect a smart query into the x/wasm handlers and see if we get the same result
   475  //	reflectAllValidatorsQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
   476  //		AllValidators: &wasmvmtypes.AllValidatorsQuery{},
   477  //	}}}}
   478  //	reflectAllValidatorsBin := buildReflectQuery(t, &reflectAllValidatorsQuery)
   479  //	res, err = keeper.QuerySmart(ctx, maskAddr, reflectAllValidatorsBin)
   480  //	require.NoError(t, err)
   481  //	// first we pull out the data from chain response, before parsing the original response
   482  //	mustParse(t, res, &reflectRes)
   483  //	var allValidatorsRes wasmvmtypes.AllValidatorsResponse
   484  //	mustParse(t, reflectRes.Data, &allValidatorsRes)
   485  //	require.Len(t, allValidatorsRes.Validators, 1)
   486  //	valInfo := allValidatorsRes.Validators[0]
   487  //	// Note: this ValAddress not AccAddress, may change with #264
   488  //	require.Equal(t, valAddr.String(), valInfo.Address)
   489  //	require.Contains(t, valInfo.Commission, "0.100")
   490  //	require.Contains(t, valInfo.MaxCommission, "0.200")
   491  //	require.Contains(t, valInfo.MaxChangeRate, "0.010")
   492  //
   493  //	// find a validator
   494  //	reflectValidatorQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
   495  //		Validator: &wasmvmtypes.ValidatorQuery{
   496  //			Address: valAddr.String(),
   497  //		},
   498  //	}}}}
   499  //	reflectValidatorBin := buildReflectQuery(t, &reflectValidatorQuery)
   500  //	res, err = keeper.QuerySmart(ctx, maskAddr, reflectValidatorBin)
   501  //	require.NoError(t, err)
   502  //	// first we pull out the data from chain response, before parsing the original response
   503  //	mustParse(t, res, &reflectRes)
   504  //	var validatorRes wasmvmtypes.ValidatorResponse
   505  //	mustParse(t, reflectRes.Data, &validatorRes)
   506  //	require.NotNil(t, validatorRes.Validator)
   507  //	valInfo = *validatorRes.Validator
   508  //	// Note: this ValAddress not AccAddress, may change with #264
   509  //	require.Equal(t, valAddr.String(), valInfo.Address)
   510  //	require.Contains(t, valInfo.Commission, "0.100")
   511  //	require.Contains(t, valInfo.MaxCommission, "0.200")
   512  //	require.Contains(t, valInfo.MaxChangeRate, "0.010")
   513  //
   514  //	// missing validator
   515  //	noVal := sdk.ValAddress(secp256k1.GenPrivKey().PubKey().Address())
   516  //	reflectNoValidatorQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
   517  //		Validator: &wasmvmtypes.ValidatorQuery{
   518  //			Address: noVal.String(),
   519  //		},
   520  //	}}}}
   521  //	reflectNoValidatorBin := buildReflectQuery(t, &reflectNoValidatorQuery)
   522  //	res, err = keeper.QuerySmart(ctx, maskAddr, reflectNoValidatorBin)
   523  //	require.NoError(t, err)
   524  //	// first we pull out the data from chain response, before parsing the original response
   525  //	mustParse(t, res, &reflectRes)
   526  //	var noValidatorRes wasmvmtypes.ValidatorResponse
   527  //	mustParse(t, reflectRes.Data, &noValidatorRes)
   528  //	require.Nil(t, noValidatorRes.Validator)
   529  //
   530  //	// test to get all my delegations
   531  //	reflectAllDelegationsQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
   532  //		AllDelegations: &wasmvmtypes.AllDelegationsQuery{
   533  //			Delegator: contractAddr.String(),
   534  //		},
   535  //	}}}}
   536  //	reflectAllDelegationsBin := buildReflectQuery(t, &reflectAllDelegationsQuery)
   537  //	res, err = keeper.QuerySmart(ctx, maskAddr, reflectAllDelegationsBin)
   538  //	require.NoError(t, err)
   539  //	// first we pull out the data from chain response, before parsing the original response
   540  //	mustParse(t, res, &reflectRes)
   541  //	var allDelegationsRes wasmvmtypes.AllDelegationsResponse
   542  //	mustParse(t, reflectRes.Data, &allDelegationsRes)
   543  //	require.Len(t, allDelegationsRes.Delegations, 1)
   544  //	delInfo := allDelegationsRes.Delegations[0]
   545  //	// Note: this ValAddress not AccAddress, may change with #264
   546  //	require.Equal(t, valAddr.String(), delInfo.Validator)
   547  //	// note this is not bob (who staked to the contract), but the contract itself
   548  //	require.Equal(t, contractAddr.String(), delInfo.Delegator)
   549  //	// this is a different Coin type, with String not BigInt, compare field by field
   550  //	require.Equal(t, funds[0].Denom, delInfo.Amount.Denom)
   551  //	require.Equal(t, funds[0].Amount.String(), delInfo.Amount.Amount)
   552  //
   553  //	// test to get one delegations
   554  //	reflectDelegationQuery := testdata.ReflectQueryMsg{Chain: &testdata.ChainQuery{Request: &wasmvmtypes.QueryRequest{Staking: &wasmvmtypes.StakingQuery{
   555  //		Delegation: &wasmvmtypes.DelegationQuery{
   556  //			Validator: valAddr.String(),
   557  //			Delegator: contractAddr.String(),
   558  //		},
   559  //	}}}}
   560  //	reflectDelegationBin := buildReflectQuery(t, &reflectDelegationQuery)
   561  //	res, err = keeper.QuerySmart(ctx, maskAddr, reflectDelegationBin)
   562  //	require.NoError(t, err)
   563  //	// first we pull out the data from chain response, before parsing the original response
   564  //	mustParse(t, res, &reflectRes)
   565  //	var delegationRes wasmvmtypes.DelegationResponse
   566  //	mustParse(t, reflectRes.Data, &delegationRes)
   567  //	assert.NotEmpty(t, delegationRes.Delegation)
   568  //	delInfo2 := delegationRes.Delegation
   569  //	// Note: this ValAddress not AccAddress, may change with #264
   570  //	require.Equal(t, valAddr.String(), delInfo2.Validator)
   571  //	// note this is not bob (who staked to the contract), but the contract itself
   572  //	require.Equal(t, contractAddr.String(), delInfo2.Delegator)
   573  //	// this is a different Coin type, with String not BigInt, compare field by field
   574  //	require.Equal(t, funds[0].Denom, delInfo2.Amount.Denom)
   575  //	require.Equal(t, funds[0].Amount.String(), delInfo2.Amount.Amount)
   576  //
   577  //	require.Equal(t, wasmvmtypes.NewCoin(200000, "stake"), delInfo2.CanRedelegate)
   578  //	require.Len(t, delInfo2.AccumulatedRewards, 1)
   579  //	// see bonding above to see how we calculate 36000 (240000 / 6 - 10% commission)
   580  //	require.Equal(t, wasmvmtypes.NewCoin(36000, "stake"), delInfo2.AccumulatedRewards[0])
   581  //
   582  //	// ensure rewards did not change when querying (neither amount nor period)
   583  //	finalReward := distKeeper.GetValidatorCurrentRewards(ctx, valAddr)
   584  //	require.Equal(t, origReward, finalReward)
   585  //}
   586  //
   587  //func TestQueryStakingPlugin(t *testing.T) {
   588  //	// STEP 1: take a lot of setup from TestReinvest so we have non-zero info
   589  //	initInfo := initializeStaking(t)
   590  //	ctx, valAddr, contractAddr := initInfo.ctx, initInfo.valAddr, initInfo.contractAddr
   591  //	stakingKeeper := initInfo.stakingKeeper
   592  //	distKeeper := initInfo.distKeeper
   593  //
   594  //	// initial checks of bonding state
   595  //	val, found := stakingKeeper.GetValidator(ctx, valAddr)
   596  //	require.True(t, found)
   597  //	assert.Equal(t, sdk.NewInt(1000000), val.Tokens)
   598  //
   599  //	// full is 2x funds, 1x goes to the contract, other stays on his wallet
   600  //	full := sdk.NewCoins(sdk.NewInt64Coin("stake", 400000))
   601  //	funds := sdk.NewCoins(sdk.NewInt64Coin("stake", 200000))
   602  //	bob := initInfo.faucet.NewFundedAccount(ctx, full...)
   603  //
   604  //	// we will stake 200k to a validator with 1M self-bond
   605  //	// this means we should get 1/6 of the rewards
   606  //	bond := StakingHandleMsg{
   607  //		Bond: &struct{}{},
   608  //	}
   609  //	bondBz, err := json.Marshal(bond)
   610  //	require.NoError(t, err)
   611  //	_, err = initInfo.contractKeeper.Execute(ctx, contractAddr, bob, bondBz, funds)
   612  //	require.NoError(t, err)
   613  //
   614  //	// update height a bit to solidify the delegation
   615  //	ctx = nextBlock(ctx, stakingKeeper)
   616  //	// we get 1/6, our share should be 40k minus 10% commission = 36k
   617  //	setValidatorRewards(ctx, stakingKeeper, distKeeper, valAddr, "240000")
   618  //
   619  //	// see what the current rewards are
   620  //	origReward := distKeeper.GetValidatorCurrentRewards(ctx, valAddr)
   621  //
   622  //	// Step 2: Try out the query plugins
   623  //	query := wasmvmtypes.StakingQuery{
   624  //		Delegation: &wasmvmtypes.DelegationQuery{
   625  //			Delegator: contractAddr.String(),
   626  //			Validator: valAddr.String(),
   627  //		},
   628  //	}
   629  //	raw, err := StakingQuerier(stakingKeeper, distKeeper)(ctx, &query)
   630  //	require.NoError(t, err)
   631  //	var res wasmvmtypes.DelegationResponse
   632  //	mustParse(t, raw, &res)
   633  //	assert.NotEmpty(t, res.Delegation)
   634  //	delInfo := res.Delegation
   635  //	// Note: this ValAddress not AccAddress, may change with #264
   636  //	require.Equal(t, valAddr.String(), delInfo.Validator)
   637  //	// note this is not bob (who staked to the contract), but the contract itself
   638  //	require.Equal(t, contractAddr.String(), delInfo.Delegator)
   639  //	// this is a different Coin type, with String not BigInt, compare field by field
   640  //	require.Equal(t, funds[0].Denom, delInfo.Amount.Denom)
   641  //	require.Equal(t, funds[0].Amount.String(), delInfo.Amount.Amount)
   642  //
   643  //	require.Equal(t, wasmvmtypes.NewCoin(200000, "stake"), delInfo.CanRedelegate)
   644  //	require.Len(t, delInfo.AccumulatedRewards, 1)
   645  //	// see bonding above to see how we calculate 36000 (240000 / 6 - 10% commission)
   646  //	require.Equal(t, wasmvmtypes.NewCoin(36000, "stake"), delInfo.AccumulatedRewards[0])
   647  //
   648  //	// ensure rewards did not change when querying (neither amount nor period)
   649  //	finalReward := distKeeper.GetValidatorCurrentRewards(ctx, valAddr)
   650  //	require.Equal(t, origReward, finalReward)
   651  //}
   652  //
   653  //// adds a few validators and returns a list of validators that are registered
   654  //func addValidator(t *testing.T, ctx sdk.Context, stakingKeeper stakingkeeper.Keeper, faucet *TestFaucet, value sdk.Coin) sdk.ValAddress {
   655  //	owner := faucet.NewFundedAccount(ctx, value)
   656  //
   657  //	privKey := secp256k1.GenPrivKey()
   658  //	pubKey := privKey.PubKey()
   659  //	addr := sdk.ValAddress(pubKey.Address())
   660  //
   661  //	pkAny, err := codectypes.NewAnyWithValue(pubKey)
   662  //	require.NoError(t, err)
   663  //	msg := stakingtypes.MsgCreateValidator{
   664  //		Description: types.Description{
   665  //			Moniker: "Validator power",
   666  //		},
   667  //		Commission: types.CommissionRates{
   668  //			Rate:          sdk.MustNewDecFromStr("0.1"),
   669  //			MaxRate:       sdk.MustNewDecFromStr("0.2"),
   670  //			MaxChangeRate: sdk.MustNewDecFromStr("0.01"),
   671  //		},
   672  //		MinSelfDelegation: sdk.OneInt(),
   673  //		DelegatorAddress:  owner.String(),
   674  //		ValidatorAddress:  addr.String(),
   675  //		Pubkey:            pkAny,
   676  //		Value:             value,
   677  //	}
   678  //
   679  //	h := staking.NewHandler(stakingKeeper)
   680  //	_, err = h(ctx, &msg)
   681  //	require.NoError(t, err)
   682  //	return addr
   683  //}
   684  //
   685  //// this will commit the current set, update the block height and set historic info
   686  //// basically, letting two blocks pass
   687  //func nextBlock(ctx sdk.Context, stakingKeeper stakingkeeper.Keeper) sdk.Context {
   688  //	staking.EndBlocker(ctx, stakingKeeper)
   689  //	ctx = ctx.WithBlockHeight(ctx.BlockHeight() + 1)
   690  //	staking.BeginBlocker(ctx, stakingKeeper)
   691  //	return ctx
   692  //}
   693  //
   694  //func setValidatorRewards(ctx sdk.Context, stakingKeeper stakingkeeper.Keeper, distKeeper distributionkeeper.Keeper, valAddr sdk.ValAddress, reward string) {
   695  //	// allocate some rewards
   696  //	vali := stakingKeeper.Validator(ctx, valAddr)
   697  //	amount, err := sdk.NewDecFromStr(reward)
   698  //	if err != nil {
   699  //		panic(err)
   700  //	}
   701  //	payout := sdk.DecCoins{{Denom: "stake", Amount: amount}}
   702  //	distKeeper.AllocateTokensToValidator(ctx, vali, payout)
   703  //}
   704  //
   705  //func assertBalance(t *testing.T, ctx sdk.Context, keeper Keeper, contract sdk.AccAddress, addr sdk.AccAddress, expected string) {
   706  //	query := StakingQueryMsg{
   707  //		Balance: &addressQuery{
   708  //			Address: addr,
   709  //		},
   710  //	}
   711  //	queryBz, err := json.Marshal(query)
   712  //	require.NoError(t, err)
   713  //	res, err := keeper.QuerySmart(ctx, contract, queryBz)
   714  //	require.NoError(t, err)
   715  //	var balance BalanceResponse
   716  //	err = json.Unmarshal(res, &balance)
   717  //	require.NoError(t, err)
   718  //	assert.Equal(t, expected, balance.Balance)
   719  //}
   720  //
   721  //func assertClaims(t *testing.T, ctx sdk.Context, keeper Keeper, contract sdk.AccAddress, addr sdk.AccAddress, expected string) {
   722  //	query := StakingQueryMsg{
   723  //		Claims: &addressQuery{
   724  //			Address: addr,
   725  //		},
   726  //	}
   727  //	queryBz, err := json.Marshal(query)
   728  //	require.NoError(t, err)
   729  //	res, err := keeper.QuerySmart(ctx, contract, queryBz)
   730  //	require.NoError(t, err)
   731  //	var claims ClaimsResponse
   732  //	err = json.Unmarshal(res, &claims)
   733  //	require.NoError(t, err)
   734  //	assert.Equal(t, expected, claims.Claims)
   735  //}
   736  //
   737  //func assertSupply(t *testing.T, ctx sdk.Context, keeper Keeper, contract sdk.AccAddress, expectedIssued string, expectedBonded sdk.Coin) {
   738  //	query := StakingQueryMsg{Investment: &struct{}{}}
   739  //	queryBz, err := json.Marshal(query)
   740  //	require.NoError(t, err)
   741  //	res, err := keeper.QuerySmart(ctx, contract, queryBz)
   742  //	require.NoError(t, err)
   743  //	var invest InvestmentResponse
   744  //	err = json.Unmarshal(res, &invest)
   745  //	require.NoError(t, err)
   746  //	assert.Equal(t, expectedIssued, invest.TokenSupply)
   747  //	assert.Equal(t, expectedBonded, invest.StakedTokens)
   748  //}