diff --git a/cmd/zetae2e/local/local.go b/cmd/zetae2e/local/local.go index 2d404ba391..de46edf450 100644 --- a/cmd/zetae2e/local/local.go +++ b/cmd/zetae2e/local/local.go @@ -330,7 +330,8 @@ func localE2ETest(cmd *cobra.Command, _ []string) { e2etests.TestPrecompilesPrototypeName, e2etests.TestPrecompilesPrototypeThroughContractName, e2etests.TestPrecompilesStakingName, - e2etests.TestPrecompilesStakingThroughContractName, + // Disabled until further notice, check https://github.com/zeta-chain/node/issues/3005. + // e2etests.TestPrecompilesStakingThroughContractName, e2etests.TestPrecompilesBankName, e2etests.TestPrecompilesBankFailName, e2etests.TestPrecompilesBankThroughContractName, 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 f3a01a541e..fea0d0f9f2 100644 --- a/precompiles/staking/staking.go +++ b/precompiles/staking/staking.go @@ -415,6 +415,12 @@ func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) ([]byt } 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, + } + + //nolint:govet if readOnly { return nil, ptypes.ErrWriteMethod{ Method: method.Name, @@ -431,6 +437,12 @@ func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) ([]byt } 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, + } + + //nolint:govet if readOnly { return nil, ptypes.ErrWriteMethod{ Method: method.Name, @@ -447,6 +459,12 @@ func (c *Contract) Run(evm *vm.EVM, contract *vm.Contract, readOnly bool) ([]byt } 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, + } + + //nolint:govet if readOnly { return nil, ptypes.ErrWriteMethod{ Method: method.Name, diff --git a/precompiles/staking/staking_test.go b/precompiles/staking/staking_test.go index 3155dd2b4b..aaea87f94d 100644 --- a/precompiles/staking/staking_test.go +++ b/precompiles/staking/staking_test.go @@ -239,7 +239,8 @@ func Test_InvalidABI(t *testing.T) { } func Test_Stake(t *testing.T) { - t.Run("should fail in read only mode", func(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] @@ -259,627 +260,295 @@ func Test_Stake(t *testing.T) { args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} mockVMContract.Input = packInputArgs(t, methodID, args...) - // ACT - _, err = contract.Run(mockEVM, mockVMContract, true) - - // ASSERT - require.ErrorIs(t, err, ptypes.ErrWriteMethod{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) { - t.Run("should fail in read only method", 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, true) - - // ASSERT - require.ErrorIs(t, err, ptypes.ErrWriteMethod{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) { - t.Run("should fail in read only method", 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, true) - - // ASSERT - require.ErrorIs(t, err, ptypes.ErrWriteMethod{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) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: StakeMethodName, + }) }) - t.Run("should move stake", func(t *testing.T) { + // t.Run("should fail in read only mode", 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, true) + + // // ASSERT + // require.ErrorIs(t, err, ptypes.ErrWriteMethod{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[MoveStakeMethodName] + methodID := abi.Methods[UnstakeMethodName] 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) + validator := sample.Validator(t, r) staker := sample.Bech32AccAddress() stakerEthAddr := common.BytesToAddress(staker.Bytes()) @@ -891,255 +560,288 @@ func Test_MoveStake(t *testing.T) { 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...) + args := []interface{}{stakerEthAddr, validator.OperatorAddress, coins.AmountOf(config.BaseDenom).BigInt()} + mockVMContract.Input = packInputArgs(t, methodID, args...) // 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) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: UnstakeMethodName, + }) }) - 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 in read only method", 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, true) + + // // ASSERT + // require.ErrorIs(t, err, ptypes.ErrWriteMethod{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) + // }) +} - t.Run("should fail if caller is not staker", func(t *testing.T) { +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] @@ -1147,7 +849,6 @@ func Test_MoveStake(t *testing.T) { 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()) @@ -1159,6 +860,7 @@ func Test_MoveStake(t *testing.T) { stakerAddr := common.BytesToAddress(staker.Bytes()) mockVMContract.CallerAddress = stakerAddr + argsStake := []interface{}{ stakerEthAddr, validatorSrc.OperatorAddress, @@ -1169,7 +871,10 @@ func Test_MoveStake(t *testing.T) { stakeMethodID := abi.Methods[StakeMethodName] mockVMContract.Input = packInputArgs(t, stakeMethodID, argsStake...) _, err = contract.Run(mockEVM, mockVMContract, false) - require.NoError(t, err) + require.Error(t, err) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: StakeMethodName, + }) argsMoveStake := []interface{}{ stakerEthAddr, @@ -1179,15 +884,427 @@ func Test_MoveStake(t *testing.T) { } 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") + require.Error(t, err) + require.ErrorIs(t, err, ptypes.ErrDisabledMethod{ + Method: MoveStakeMethodName, + }) }) + + // t.Run("should fail in read only method", 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, true) + + // // ASSERT + // require.ErrorIs(t, err, ptypes.ErrWriteMethod{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) { 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 }