From 80dfd0864b037eafe57ab76859af3df3218e156a Mon Sep 17 00:00:00 2001 From: Francisco de Borja Aranda Castillejo Date: Thu, 17 Oct 2024 13:02:20 +0200 Subject: [PATCH] explicitly check for failed tx when staking --- cmd/zetae2e/local/local.go | 3 +- e2e/e2etests/e2etests.go | 2 +- e2e/e2etests/test_precompiles_staking.go | 52 + precompiles/staking/staking.go | 113 +- precompiles/staking/staking_test.go | 1816 ++++++++++++---------- precompiles/types/errors.go | 8 + 6 files changed, 1094 insertions(+), 900 deletions(-) diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 8081ba6759..de46edf450 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -329,7 +329,8 @@ func localE2ETest(cmd *cobra.Command, _ []string) { precompiledContractTests = []string{ e2etests.TestPrecompilesPrototypeName, e2etests.TestPrecompilesPrototypeThroughContractName, - // e2etests.TestPrecompilesStakingName, + e2etests.TestPrecompilesStakingName, + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. // e2etests.TestPrecompilesStakingThroughContractName, e2etests.TestPrecompilesBankName, e2etests.TestPrecompilesBankFailName, diff --git a/e2e/e2etests/e2etests.go b/e2e/e2etests/e2etests.go index 2d6eea998f..fe6428385d 100644 --- a/e2e/e2etests/e2etests.go +++ b/e2e/e2etests/e2etests.go @@ -930,7 +930,7 @@ var AllE2ETests = []runner.E2ETest{ TestPrecompilesStakingName, "test stateful precompiled contracts staking", []runner.ArgDefinition{}, - TestPrecompilesStaking, + TestPrecompilesStakingIsDisabled, ), runner.NewE2ETest( TestPrecompilesStakingThroughContractName, diff --git a/e2e/e2etests/test_precompiles_staking.go b/e2e/e2etests/test_precompiles_staking.go index 7b1fc44e1c..37a7e152de 100644 --- a/e2e/e2etests/test_precompiles_staking.go +++ b/e2e/e2etests/test_precompiles_staking.go @@ -13,6 +13,58 @@ import ( "github.com/zeta-chain/node/precompiles/staking" ) +func TestPrecompilesStakingIsDisabled(r *runner.E2ERunner, args []string) { + require.Len(r, args, 0, "No arguments expected") + + stakingContract, err := staking.NewIStaking(staking.ContractAddress, r.ZEVMClient) + require.NoError(r, err, "Failed to create staking contract caller") + + previousGasLimit := r.ZEVMAuth.GasLimit + r.ZEVMAuth.GasLimit = 10000000 + defer func() { + r.ZEVMAuth.GasLimit = previousGasLimit + }() + + validators, err := stakingContract.GetAllValidators(&bind.CallOpts{}) + require.NoError(r, err) + require.GreaterOrEqual(r, len(validators), 2) + + CleanValidatorDelegations(r, stakingContract, validators) + + // shares are 0 for both validators at the start + sharesBeforeVal1, err := stakingContract.GetShares(&bind.CallOpts{}, r.ZEVMAuth.From, validators[0].OperatorAddress) + require.NoError(r, err) + require.Equal(r, int64(0), sharesBeforeVal1.Int64()) + + sharesBeforeVal2, err := stakingContract.GetShares(&bind.CallOpts{}, r.ZEVMAuth.From, validators[1].OperatorAddress) + require.NoError(r, err) + require.Equal(r, int64(0), sharesBeforeVal2.Int64()) + + // stake 3 to validator1 + tx, err := stakingContract.Stake(r.ZEVMAuth, r.ZEVMAuth.From, validators[0].OperatorAddress, big.NewInt(3)) + require.NoError(r, err) + receipt := utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt) + + // unstake 1 from validator1 + tx, err = stakingContract.Unstake(r.ZEVMAuth, r.ZEVMAuth.From, validators[0].OperatorAddress, big.NewInt(1)) + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt) + + // move 1 stake from validator1 to validator2 + tx, err = stakingContract.MoveStake( + r.ZEVMAuth, + r.ZEVMAuth.From, + validators[0].OperatorAddress, + validators[1].OperatorAddress, + big.NewInt(1), + ) + require.NoError(r, err) + receipt = utils.MustWaitForTxReceipt(r.Ctx, r.ZEVMClient, tx, r.Logger, r.ReceiptTimeout) + utils.RequiredTxFailed(r, receipt) +} + func TestPrecompilesStaking(r *runner.E2ERunner, args []string) { require.Len(r, args, 0, "No arguments expected") diff --git a/precompiles/staking/staking.go b/precompiles/staking/staking.go index 3474b60ba5..761730b188 100644 --- a/precompiles/staking/staking.go +++ b/precompiles/staking/staking.go @@ -380,7 +380,7 @@ func (c *Contract) MoveStake( // Run is the entrypoint of the precompiled contract, it switches over the input method, // and execute them accordingly. -func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, error) { +func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) ([]byte, error) { method, err := ABI.MethodById(contract.Input[:4]) if err != nil { return nil, err @@ -414,54 +414,69 @@ func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, _ bool) ([]byte, erro return nil, err } return res, nil - // case StakeMethodName: - // if readOnly { - // return nil, ptypes.ErrWriteMethod{ - // Method: method.Name, - // } - // } - - // var res []byte - // execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { - // res, err = c.Stake(ctx, evm, contract, method, args) - // return err - // }) - // if execErr != nil { - // return nil, err - // } - // return res, nil - // case UnstakeMethodName: - // if readOnly { - // return nil, ptypes.ErrWriteMethod{ - // Method: method.Name, - // } - // } - - // var res []byte - // execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { - // res, err = c.Unstake(ctx, evm, contract, method, args) - // return err - // }) - // if execErr != nil { - // return nil, err - // } - // return res, nil - // case MoveStakeMethodName: - // if readOnly { - // return nil, ptypes.ErrWriteMethod{ - // Method: method.Name, - // } - // } - - // var res []byte - // execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { - // res, err = c.MoveStake(ctx, evm, contract, method, args) - // return err - // }) - // if execErr != nil { - // return nil, err - // } - // return res, nil + case StakeMethodName: + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. + return nil, ptypes.ErrDisabledMethod{ + Method: method.Name, + } + + if readOnly { + return nil, ptypes.ErrWriteMethod{ + Method: method.Name, + } + } + + var res []byte + execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + res, err = c.Stake(ctx, evm, contract, method, args) + return err + }) + if execErr != nil { + return nil, err + } + return res, nil + case UnstakeMethodName: + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. + return nil, ptypes.ErrDisabledMethod{ + Method: method.Name, + } + + if readOnly { + return nil, ptypes.ErrWriteMethod{ + Method: method.Name, + } + } + + var res []byte + execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + res, err = c.Unstake(ctx, evm, contract, method, args) + return err + }) + if execErr != nil { + return nil, err + } + return res, nil + case MoveStakeMethodName: + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. + return nil, ptypes.ErrDisabledMethod{ + Method: method.Name, + } + + if readOnly { + return nil, ptypes.ErrWriteMethod{ + Method: method.Name, + } + } + + var res []byte + execErr := stateDB.ExecuteNativeAction(contract.Address(), nil, func(ctx sdk.Context) error { + res, err = c.MoveStake(ctx, evm, contract, method, args) + return err + }) + if execErr != nil { + return nil, err + } + return res, nil default: return nil, ptypes.ErrInvalidMethod{ diff --git a/precompiles/staking/staking_test.go b/precompiles/staking/staking_test.go index 05b5f00e87..c8d7538ffe 100644 --- a/precompiles/staking/staking_test.go +++ b/precompiles/staking/staking_test.go @@ -25,6 +25,7 @@ import ( "github.com/zeta-chain/node/precompiles/prototype" "github.com/zeta-chain/node/testutil/keeper" + ptypes "github.com/zeta-chain/node/precompiles/types" "github.com/zeta-chain/node/testutil/sample" fungibletypes "github.com/zeta-chain/node/x/fungible/types" ) @@ -237,855 +238,972 @@ func Test_InvalidABI(t *testing.T) { initABI() } -// func Test_Stake(t *testing.T) { -// t.Run("should fail if validator doesn't exist", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} -// mockVMContract.Input = packInputArgs(t, methodID, args...) - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should stake", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} -// mockVMContract.Input = packInputArgs(t, methodID, args...) - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.NoError(t, err) -// }) - -// t.Run("should fail if no input args", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr -// mockVMContract.Input = methodID.ID - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if caller is not staker", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr - -// nonStakerAddr := common.BytesToAddress(sample.Bech32AccAddress().Bytes()) -// args := []interface{}{nonStakerAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} -// mockVMContract.Input = packInputArgs(t, methodID, args...) - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.ErrorContains(t, err, "caller is not staker address") -// }) - -// t.Run("should fail if staking fails", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// // staker without funds -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} -// mockVMContract.Input = packInputArgs(t, methodID, args...) - -// // ACT -// _, err := contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if wrong args amount", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress} - -// // ACT -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if staker is not eth addr", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{staker, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} - -// // ACT -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if validator is not valid string", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{stakerEthAddr, 42, coins.AmountOf(config.BaseDenom).BigInt()} - -// // ACT -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if amount is not int64", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[StakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).Uint64()} - -// // ACT -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) -// } - -// func Test_Unstake(t *testing.T) { -// t.Run("should fail if validator doesn't exist", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} -// mockVMContract.Input = packInputArgs(t, methodID, args...) - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should unstake", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} - -// // stake first -// stakeMethodID := abi.Methods[StakeMethodName] -// mockVMContract.Input = packInputArgs(t, stakeMethodID, args...) -// _, err = contract.Run(mockEVM, mockVMContract, false) -// require.NoError(t, err) - -// // ACT -// mockVMContract.Input = packInputArgs(t, methodID, args...) -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.NoError(t, err) -// }) - -// t.Run("should fail if caller is not staker", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} -// // stake first -// stakeMethodID := abi.Methods[StakeMethodName] -// mockVMContract.Input = packInputArgs(t, stakeMethodID, args...) -// _, err = contract.Run(mockEVM, mockVMContract, false) -// require.NoError(t, err) - -// callerEthAddr := common.BytesToAddress(sample.Bech32AccAddress().Bytes()) -// mockVMContract.CallerAddress = callerEthAddr -// mockVMContract.Input = packInputArgs(t, methodID, args...) - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.ErrorContains(t, err, "caller is not staker address") -// }) - -// t.Run("should fail if no previous staking", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} -// mockVMContract.Input = packInputArgs(t, methodID, args...) - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if wrong args amount", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress} - -// // ACT -// _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if staker is not eth addr", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{staker, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} - -// // ACT -// _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if validator is not valid string", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{stakerEthAddr, 42, coins.AmountOf(config.BaseDenom).BigInt()} - -// // ACT -// _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if amount is not int64", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[UnstakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validator := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validator) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).Uint64()} - -// // ACT -// _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) - -// // ASSERT -// require.Error(t, err) -// }) -// } - -// func Test_MoveStake(t *testing.T) { -// t.Run("should fail if validator dest doesn't exist", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr - -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) -// _, err = contract.Run(mockEVM, mockVMContract, false) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// validatorDest.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } -// mockVMContract.Input = packInputArgs(t, methodID, argsMoveStake...) - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should move stake", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) -// _, err = contract.Run(mockEVM, mockVMContract, false) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// validatorDest.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } -// mockVMContract.Input = packInputArgs(t, methodID, argsMoveStake...) - -// // ACT -// // move stake to validator dest -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.NoError(t, err) -// }) - -// t.Run("should fail if staker is invalid arg", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{ -// 42, -// validatorSrc.OperatorAddress, -// validatorDest.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // ACT -// _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if validator src is invalid arg", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{ -// stakerEthAddr, -// 42, -// validatorDest.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // ACT -// _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if validator dest is invalid arg", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// 42, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // ACT -// _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if amount is invalid arg", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// validatorDest.OperatorAddress, -// coins.AmountOf(config.BaseDenom).Uint64(), -// } - -// // ACT -// _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if wrong args amount", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) - -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{stakerEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress} - -// // ACT -// _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) - -// // ASSERT -// require.Error(t, err) -// }) - -// t.Run("should fail if caller is not staker", func(t *testing.T) { -// // ARRANGE -// ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) -// methodID := abi.Methods[MoveStakeMethodName] -// r := rand.New(rand.NewSource(42)) -// validatorSrc := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) -// validatorDest := sample.Validator(t, r) -// sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) - -// staker := sample.Bech32AccAddress() -// stakerEthAddr := common.BytesToAddress(staker.Bytes()) -// coins := sample.Coins() -// err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) -// require.NoError(t, err) -// err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) -// require.NoError(t, err) - -// stakerAddr := common.BytesToAddress(staker.Bytes()) -// mockVMContract.CallerAddress = stakerAddr -// argsStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } - -// // stake to validator src -// stakeMethodID := abi.Methods[StakeMethodName] -// mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) -// _, err = contract.Run(mockEVM, mockVMContract, false) -// require.NoError(t, err) - -// argsMoveStake := []interface{}{ -// stakerEthAddr, -// validatorSrc.OperatorAddress, -// validatorDest.OperatorAddress, -// coins.AmountOf(config.BaseDenom).BigInt(), -// } -// mockVMContract.Input = packInputArgs(t, methodID, argsMoveStake...) - -// callerEthAddr := common.BytesToAddress(sample.Bech32AccAddress().Bytes()) -// mockVMContract.CallerAddress = callerEthAddr - -// // ACT -// _, err = contract.Run(mockEVM, mockVMContract, false) - -// // ASSERT -// require.ErrorContains(t, err, "caller is not staker") -// }) -// } +func Test_Stake(t *testing.T) { + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. + t.Run("should fail with error disabled", func(t *testing.T) { + // ARRANGE + ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + methodID := abi.Methods[StakeMethodName] + r := rand.New(rand.NewSource(42)) + validator := sample.Validator(t, r) + + staker := sample.Bech32AccAddress() + stakerEthAddr := common.BytesToAddress(staker.Bytes()) + coins := sample.Coins() + err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + require.NoError(t, err) + err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + require.NoError(t, err) + + stakerAddr := common.BytesToAddress(staker.Bytes()) + mockVMContract.CallerAddress = stakerAddr + args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + mockVMContract.Input = packInputArgs(t, methodID, args...) + + // ACT + _, err = contract.Run(mockEVM, mockVMContract, false) + + // ASSERT + require.Error(t, err) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: StakeMethodName, + }) + }) + + // t.Run("should fail if validator doesn't exist", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + // mockVMContract.Input = packInputArgs(t, methodID, args...) + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should stake", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + // mockVMContract.Input = packInputArgs(t, methodID, args...) + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.NoError(t, err) + // }) + + // t.Run("should fail if no input args", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + // mockVMContract.Input = methodID.ID + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if caller is not staker", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + + // nonStakerAddr := common.BytesToAddress(sample.Bech32AccAddress().Bytes()) + // args := []interface{}{nonStakerAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + // mockVMContract.Input = packInputArgs(t, methodID, args...) + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.ErrorContains(t, err, "caller is not staker address") + // }) + + // t.Run("should fail if staking fails", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // // staker without funds + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + // mockVMContract.Input = packInputArgs(t, methodID, args...) + + // // ACT + // _, err := contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if wrong args amount", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress} + + // // ACT + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if staker is not eth addr", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{staker, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + + // // ACT + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if validator is not valid string", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{stakerEthAddr, 42, coins.AmountOf(config.BaseDenom).BigInt()} + + // // ACT + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if amount is not int64", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[StakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).Uint64()} + + // // ACT + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) +} + +func Test_Unstake(t *testing.T) { + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. + t.Run("should fail with error disabled", func(t *testing.T) { + // ARRANGE + ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + methodID := abi.Methods[UnstakeMethodName] + r := rand.New(rand.NewSource(42)) + validator := sample.Validator(t, r) + + staker := sample.Bech32AccAddress() + stakerEthAddr := common.BytesToAddress(staker.Bytes()) + coins := sample.Coins() + err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + require.NoError(t, err) + err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + require.NoError(t, err) + + stakerAddr := common.BytesToAddress(staker.Bytes()) + mockVMContract.CallerAddress = stakerAddr + + args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + mockVMContract.Input = packInputArgs(t, methodID, args...) + + // ACT + _, err = contract.Run(mockEVM, mockVMContract, false) + + // ASSERT + require.Error(t, err) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: UnstakeMethodName, + }) + }) + + // t.Run("should fail if validator doesn't exist", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + // mockVMContract.Input = packInputArgs(t, methodID, args...) + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should unstake", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + + // // stake first + // stakeMethodID := abi.Methods[StakeMethodName] + // mockVMContract.Input = packInputArgs(t, stakeMethodID, args...) + // _, err = contract.Run(mockEVM, mockVMContract, false) + // require.NoError(t, err) + + // // ACT + // mockVMContract.Input = packInputArgs(t, methodID, args...) + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.NoError(t, err) + // }) + + // t.Run("should fail if caller is not staker", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + // // stake first + // stakeMethodID := abi.Methods[StakeMethodName] + // mockVMContract.Input = packInputArgs(t, stakeMethodID, args...) + // _, err = contract.Run(mockEVM, mockVMContract, false) + // require.NoError(t, err) + + // callerEthAddr := common.BytesToAddress(sample.Bech32AccAddress().Bytes()) + // mockVMContract.CallerAddress = callerEthAddr + // mockVMContract.Input = packInputArgs(t, methodID, args...) + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.ErrorContains(t, err, "caller is not staker address") + // }) + + // t.Run("should fail if no previous staking", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + // mockVMContract.Input = packInputArgs(t, methodID, args...) + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if wrong args amount", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress} + + // // ACT + // _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if staker is not eth addr", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{staker, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + + // // ACT + // _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if validator is not valid string", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{stakerEthAddr, 42, coins.AmountOf(config.BaseDenom).BigInt()} + + // // ACT + // _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if amount is not int64", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[UnstakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validator := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validator) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).Uint64()} + + // // ACT + // _, err = contract.Unstake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, args) + + // // ASSERT + // require.Error(t, err) + // }) +} + +func Test_MoveStake(t *testing.T) { + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. + t.Run("should fail with error disabled", func(t *testing.T) { + // ARRANGE + ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + methodID := abi.Methods[MoveStakeMethodName] + r := rand.New(rand.NewSource(42)) + validatorSrc := sample.Validator(t, r) + sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + validatorDest := sample.Validator(t, r) + + staker := sample.Bech32AccAddress() + stakerEthAddr := common.BytesToAddress(staker.Bytes()) + coins := sample.Coins() + err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + require.NoError(t, err) + err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + require.NoError(t, err) + + stakerAddr := common.BytesToAddress(staker.Bytes()) + mockVMContract.CallerAddress = stakerAddr + + argsStake := []interface{}{ + stakerEthAddr, + validatorSrc.OperatorAddress, + coins.AmountOf(config.BaseDenom).BigInt(), + } + + // stake to validator src + stakeMethodID := abi.Methods[StakeMethodName] + mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) + _, err = contract.Run(mockEVM, mockVMContract, false) + require.Error(t, err) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: StakeMethodName, + }) + + argsMoveStake := []interface{}{ + stakerEthAddr, + validatorSrc.OperatorAddress, + validatorDest.OperatorAddress, + coins.AmountOf(config.BaseDenom).BigInt(), + } + mockVMContract.Input = packInputArgs(t, methodID, argsMoveStake...) + + // ACT + _, err = contract.Run(mockEVM, mockVMContract, false) + + // ASSERT + require.Error(t, err) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: MoveStakeMethodName, + }) + }) + + // t.Run("should fail if validator dest doesn't exist", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) + // _, err = contract.Run(mockEVM, mockVMContract, false) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // validatorDest.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + // mockVMContract.Input = packInputArgs(t, methodID, argsMoveStake...) + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should move stake", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) + // _, err = contract.Run(mockEVM, mockVMContract, false) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // validatorDest.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + // mockVMContract.Input = packInputArgs(t, methodID, argsMoveStake...) + + // // ACT + // // move stake to validator dest + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.NoError(t, err) + // }) + + // t.Run("should fail if staker is invalid arg", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{ + // 42, + // validatorSrc.OperatorAddress, + // validatorDest.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // ACT + // _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if validator src is invalid arg", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{ + // stakerEthAddr, + // 42, + // validatorDest.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // ACT + // _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if validator dest is invalid arg", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // 42, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // ACT + // _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if amount is invalid arg", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // validatorDest.OperatorAddress, + // coins.AmountOf(config.BaseDenom).Uint64(), + // } + + // // ACT + // _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if wrong args amount", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, _ := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // _, err = contract.Stake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &stakeMethodID, argsStake) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{stakerEthAddr, validatorSrc.OperatorAddress, validatorDest.OperatorAddress} + + // // ACT + // _, err = contract.MoveStake(ctx, mockEVM, &vm.Contract{CallerAddress: stakerAddr}, &methodID, argsMoveStake) + + // // ASSERT + // require.Error(t, err) + // }) + + // t.Run("should fail if caller is not staker", func(t *testing.T) { + // // ARRANGE + // ctx, contract, abi, sdkKeepers, mockEVM, mockVMContract := setup(t) + // methodID := abi.Methods[MoveStakeMethodName] + // r := rand.New(rand.NewSource(42)) + // validatorSrc := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorSrc) + // validatorDest := sample.Validator(t, r) + // sdkKeepers.StakingKeeper.SetValidator(ctx, validatorDest) + + // staker := sample.Bech32AccAddress() + // stakerEthAddr := common.BytesToAddress(staker.Bytes()) + // coins := sample.Coins() + // err := sdkKeepers.BankKeeper.MintCoins(ctx, fungibletypes.ModuleName, sample.Coins()) + // require.NoError(t, err) + // err = sdkKeepers.BankKeeper.SendCoinsFromModuleToAccount(ctx, fungibletypes.ModuleName, staker, coins) + // require.NoError(t, err) + + // stakerAddr := common.BytesToAddress(staker.Bytes()) + // mockVMContract.CallerAddress = stakerAddr + // argsStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + + // // stake to validator src + // stakeMethodID := abi.Methods[StakeMethodName] + // mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) + // _, err = contract.Run(mockEVM, mockVMContract, false) + // require.NoError(t, err) + + // argsMoveStake := []interface{}{ + // stakerEthAddr, + // validatorSrc.OperatorAddress, + // validatorDest.OperatorAddress, + // coins.AmountOf(config.BaseDenom).BigInt(), + // } + // mockVMContract.Input = packInputArgs(t, methodID, argsMoveStake...) + + // callerEthAddr := common.BytesToAddress(sample.Bech32AccAddress().Bytes()) + // mockVMContract.CallerAddress = callerEthAddr + + // // ACT + // _, err = contract.Run(mockEVM, mockVMContract, false) + + // // ASSERT + // require.ErrorContains(t, err, "caller is not staker") + // }) +} func Test_GetAllValidators(t *testing.T) { t.Run("should return empty array if validators not set", func(t *testing.T) { diff --git a/precompiles/types/errors.go b/precompiles/types/errors.go index a624ab27af..b1ad69d258 100644 --- a/precompiles/types/errors.go +++ b/precompiles/types/errors.go @@ -94,6 +94,14 @@ func (e ErrInvalidMethod) Error() string { return fmt.Sprintf("invalid method: %s", e.Method) } +type ErrDisabledMethod struct { + Method string +} + +func (e ErrDisabledMethod) Error() string { + return fmt.Sprintf("method %s is disabled", e.Method) +} + type ErrWriteMethod struct { Method string }