Skip to content

Commit

Permalink
refactor: allow zeta deposits to new zevm address (#2076)
Browse files Browse the repository at this point in the history
* allow zevm coin deposit to unknow addresses

* add e2e tests

* add changelog

* add comments
  • Loading branch information
kingpinXD authored Apr 25, 2024
1 parent a124ffb commit 514cea7
Show file tree
Hide file tree
Showing 7 changed files with 62 additions and 25 deletions.
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

0 comments on commit 514cea7

Please sign in to comment.