Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: allow zeta deposits to new zevm address #2076

Merged
merged 4 commits into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
* [1989](https://github.com/zeta-chain/node/pull/1989) - simplify `IsSendOutTxProcessed` method and add unit tests
* [2013](https://github.com/zeta-chain/node/pull/2013) - rename `GasPriceVoter` message to `VoteGasPrice`
* [2059](https://github.com/zeta-chain/node/pull/2059) - Remove unused params from all functions in zetanode
* [2076](https://github.com/zeta-chain/node/pull/2076) - automatically deposit native zeta to an address if it doesn't exist on ZEVM.

### Features

Expand Down
2 changes: 2 additions & 0 deletions cmd/zetae2e/local/local.go
Original file line number Diff line number Diff line change
Expand Up @@ -257,6 +257,8 @@ func localE2ETest(cmd *cobra.Command, _ []string) {
e2etests.TestMessagePassingEVMtoZEVMName,
e2etests.TestMessagePassingEVMtoZEVMRevertName,
e2etests.TestMessagePassingZEVMtoEVMRevertName,
e2etests.TestZetaDepositName,
e2etests.TestZetaDepositNewAddressName,
}
bitcoinTests := []string{
e2etests.TestBitcoinWithdrawSegWitName,
Expand Down
9 changes: 9 additions & 0 deletions e2e/e2etests/e2etests.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ const (
TestEtherWithdrawRestrictedName = "eth_withdraw_restricted"
TestBitcoinDepositName = "bitcoin_deposit"
TestZetaDepositName = "zeta_deposit"
TestZetaDepositNewAddressName = "zeta_deposit_new_address"
TestZetaDepositRestrictedName = "zeta_deposit_restricted"

TestDonationEtherName = "donation_ether"
Expand Down Expand Up @@ -120,6 +121,14 @@ var AllE2ETests = []runner.E2ETest{
},
TestZetaDeposit,
),
runner.NewE2ETest(
TestZetaDepositNewAddressName,
"deposit ZETA from Ethereum to a new ZEVM address which does not exist yet",
[]runner.ArgDefinition{
runner.ArgDefinition{Description: "amount in azeta", DefaultValue: "1000000000000000000"},
},
TestZetaDepositNewAddress,
),
runner.NewE2ETest(
TestZetaWithdrawBTCRevertName,
"sending ZETA from ZEVM to Bitcoin with a message that should revert cctxs",
Expand Down
19 changes: 19 additions & 0 deletions e2e/e2etests/test_zeta_deposit.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/zeta-chain/zetacore/e2e/runner"
"github.com/zeta-chain/zetacore/e2e/utils"
"github.com/zeta-chain/zetacore/testutil/sample"
"github.com/zeta-chain/zetacore/zetaclient/testutils"
)

Expand All @@ -26,6 +27,24 @@ func TestZetaDeposit(r *runner.E2ERunner, args []string) {
r.Logger.CCTX(*cctx, "deposit")
}

func TestZetaDepositNewAddress(r *runner.E2ERunner, args []string) {
if len(args) != 1 {
panic("TestZetaDepositNewAddress requires exactly one argument for the amount.")
}

amount, ok := big.NewInt(0).SetString(args[0], 10)
if !ok {
panic("Invalid amount specified for TestZetaDepositNewAddress.")
}

newAddress := sample.EthAddress()
hash := r.DepositZetaWithAmount(newAddress, amount)

// wait for the cctx to be mined
cctx := utils.WaitCctxMinedByInTxHash(r.Ctx, hash.Hex(), r.CctxClient, r.Logger, r.CctxTimeout)
r.Logger.CCTX(*cctx, "deposit")
}

func TestZetaDepositRestricted(r *runner.E2ERunner, args []string) {
if len(args) != 1 {
panic("TestZetaDepositRestricted requires exactly one argument for the amount.")
Expand Down
15 changes: 14 additions & 1 deletion x/crosschain/keeper/process_outbound_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"math/big"
"testing"

"cosmossdk.io/errors"
ethcommon "github.com/ethereum/go-ethereum/common"
"github.com/evmos/ethermint/x/evm/statedb"
"github.com/stretchr/testify/mock"
Expand Down Expand Up @@ -77,10 +78,22 @@ func TestKeeper_ProcessFailedOutbound(t *testing.T) {
})

t.Run("unable to process failed outbound if ZETARevertAndCallContract fails", func(t *testing.T) {
k, ctx, _, _ := keepertest.CrosschainKeeper(t)
k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{
UseFungibleMock: true,
})
fungibleMock := keepertest.GetCrosschainFungibleMock(t, k)
receiver := sample.EthAddress()
errorFailedZETARevertAndCallContract := errors.New("test", 999, "failed ZETARevertAndCallContract")
cctx := GetERC20Cctx(t, receiver, chains.GoerliChain(), "", big.NewInt(42))
cctx.InboundTxParams.SenderChainId = chains.ZetaChainMainnet().ChainId
fungibleMock.On("ZETARevertAndCallContract", mock.Anything,
ethcommon.HexToAddress(cctx.InboundTxParams.Sender),
ethcommon.HexToAddress(cctx.GetCurrentOutTxParam().Receiver),
cctx.InboundTxParams.SenderChainId,
cctx.GetCurrentOutTxParam().ReceiverChainId,
cctx.GetCurrentOutTxParam().Amount.BigInt(),
mock.Anything,
mock.Anything).Return(nil, errorFailedZETARevertAndCallContract).Once()
err := k.ProcessFailedOutbound(ctx, cctx, sample.String())
require.ErrorContains(t, err, "failed ZETARevertAndCallContract")
})
Expand Down
20 changes: 11 additions & 9 deletions x/fungible/keeper/zevm_message_passing_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ func TestKeeper_ZEVMDepositAndCallContract(t *testing.T) {
require.Equal(t, inboundAmount.Int64(), b.Amount.Int64())
})

t.Run("fail ZETADepositAndCallContract if account not found", func(t *testing.T) {
k, ctx, _, _ := keepertest.FungibleKeeper(t)
t.Run("automatically deposit coin if account not found", func(t *testing.T) {
k, ctx, sdkk, _ := keepertest.FungibleKeeper(t)
_ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName)

zetaTxSender := sample.EthAddress()
Expand All @@ -96,11 +96,12 @@ func TestKeeper_ZEVMDepositAndCallContract(t *testing.T) {
cctxIndexBytes := [32]byte{}

_, err := k.ZETADepositAndCallContract(ctx, zetaTxSender, zetaTxReceiver, inboundSenderChainID, inboundAmount, data, cctxIndexBytes)
require.ErrorIs(t, err, types.ErrAccountNotFound)
require.ErrorContains(t, err, "account not found")
require.NoError(t, err)
b := sdkk.BankKeeper.GetBalance(ctx, sdk.AccAddress(zetaTxReceiver.Bytes()), config.BaseDenom)
require.Equal(t, inboundAmount.Int64(), b.Amount.Int64())
})

t.Run("fail ZETADepositAndCallContract id Deposit Fails", func(t *testing.T) {
t.Run("fail ZETADepositAndCallContract if Deposit Fails", func(t *testing.T) {
k, ctx, sdkk, _ := keepertest.FungibleKeeperWithMocks(t, keepertest.FungibleMockOptions{UseBankMock: true})
_ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName)

Expand Down Expand Up @@ -196,8 +197,8 @@ func TestKeeper_ZEVMRevertAndCallContract(t *testing.T) {
require.Equal(t, amount.Int64(), b.Amount.Int64())
})

t.Run("fail ZETARevertAndCallContract if account not found", func(t *testing.T) {
k, ctx, _, _ := keepertest.FungibleKeeper(t)
t.Run("automatically deposit coin if account not found", func(t *testing.T) {
k, ctx, sdkk, _ := keepertest.FungibleKeeper(t)
_ = k.GetAuthKeeper().GetModuleAccount(ctx, types.ModuleName)

zetaTxSender := sample.EthAddress()
Expand All @@ -209,8 +210,9 @@ func TestKeeper_ZEVMRevertAndCallContract(t *testing.T) {
cctxIndexBytes := [32]byte{}

_, err := k.ZETARevertAndCallContract(ctx, zetaTxSender, zetaTxReceiver, senderChainID.Int64(), destinationChainID.Int64(), amount, data, cctxIndexBytes)
require.ErrorIs(t, err, types.ErrAccountNotFound)
require.ErrorContains(t, err, "account not found")
require.NoError(t, err)
b := sdkk.BankKeeper.GetBalance(ctx, sdk.AccAddress(zetaTxSender.Bytes()), config.BaseDenom)
require.Equal(t, amount.Int64(), b.Amount.Int64())
})

t.Run("fail ZETARevertAndCallContract if Deposit Fails", func(t *testing.T) {
Expand Down
21 changes: 6 additions & 15 deletions x/fungible/keeper/zevm_msg_passing.go
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
package keeper

import (
"fmt"
"math/big"

"cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
ethcommon "github.com/ethereum/go-ethereum/common"
evmtypes "github.com/evmos/ethermint/x/evm/types"
"github.com/zeta-chain/zetacore/x/fungible/types"
)

// ZEVMDepositAndCallContract deposits ZETA to the to address if its an account
// If it's not an account it calls onReceive function of the connector contract and provides the address as the destinationAddress
// ZETADepositAndCallContract deposits native ZETA to the to address if its an account or if the account does not exist yet
// If it's not an account it calls onReceive function of the connector contract and provides the address as the destinationAddress .The amount of tokens is minted to the fungible module account, wrapped and sent to the contract
func (k Keeper) ZETADepositAndCallContract(ctx sdk.Context,
sender ethcommon.Address,
to ethcommon.Address,
Expand All @@ -21,10 +18,7 @@ func (k Keeper) ZETADepositAndCallContract(ctx sdk.Context,
data []byte,
indexBytes [32]byte) (*evmtypes.MsgEthereumTxResponse, error) {
acc := k.evmKeeper.GetAccount(ctx, to)
if acc == nil {
return nil, errors.Wrap(types.ErrAccountNotFound, fmt.Sprintf("address: %s", to.String()))
}
if !acc.IsContract() {
if acc == nil || !acc.IsContract() {
err := k.DepositCoinZeta(ctx, to, inboundAmount)
if err != nil {
return nil, err
Expand All @@ -35,8 +29,8 @@ func (k Keeper) ZETADepositAndCallContract(ctx sdk.Context,
return k.CallOnReceiveZevmConnector(ctx, sender.Bytes(), big.NewInt(inboundSenderChainID), to, inboundAmount, data, indexBytes)
}

// ZEVMRevertAndCallContract deposits ZETA to the sender address if its an account
// If it's not an account it calls onRevert function of the connector contract and provides the sender address as the zetaTxSenderAddress
// ZETARevertAndCallContract deposits native ZETA to the sender address if its account or if the account does not exist yet
// If it's not an account it calls onRevert function of the connector contract and provides the sender address as the zetaTxSenderAddress.The amount of tokens is minted to the fungible module account, wrapped and sent to the contract
func (k Keeper) ZETARevertAndCallContract(ctx sdk.Context,
sender ethcommon.Address,
to ethcommon.Address,
Expand All @@ -46,10 +40,7 @@ func (k Keeper) ZETARevertAndCallContract(ctx sdk.Context,
data []byte,
indexBytes [32]byte) (*evmtypes.MsgEthereumTxResponse, error) {
acc := k.evmKeeper.GetAccount(ctx, sender)
if acc == nil {
return nil, errors.Wrap(types.ErrAccountNotFound, fmt.Sprintf("address: %s", to.String()))
}
if !acc.IsContract() {
if acc == nil || !acc.IsContract() {
err := k.DepositCoinZeta(ctx, sender, remainingAmount)
if err != nil {
return nil, err
Expand Down
Loading