Skip to content

Commit

Permalink
add positive tests for refund
Browse files Browse the repository at this point in the history
  • Loading branch information
kingpinXD committed Feb 7, 2024
1 parent 9e9f698 commit e5e1bbd
Show file tree
Hide file tree
Showing 4 changed files with 192 additions and 130 deletions.
127 changes: 0 additions & 127 deletions x/crosschain/keeper/cctx_utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import (
"math/big"
"testing"

"cosmossdk.io/math"

"github.com/stretchr/testify/require"
"github.com/zeta-chain/zetacore/common"
keepertest "github.com/zeta-chain/zetacore/testutil/keeper"
Expand All @@ -14,131 +12,6 @@ import (
fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types"
)

func TestKeeper_RefundAmountOnZetaChain(t *testing.T) {
t.Run("should refund amount on zeta chain", func(t *testing.T) {
k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t)
k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName)
asset := sample.EthAddress().String()
sender := sample.EthAddress()
chainID := getValidEthChainID(t)

// deploy zrc20
deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper)
zrc20Addr := deployZRC20(
t,
ctx,
zk.FungibleKeeper,
sdkk.EvmKeeper,
chainID,
"bar",
asset,
"bar",
)

err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: chainID,
Sender: sender.String(),
Asset: asset,
Amount: math.NewUint(42),
}},
)
require.NoError(t, err)

// check amount deposited in balance
balance, err := zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender)
require.NoError(t, err)
require.Equal(t, uint64(42), balance.Uint64())

// can refund again
err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: chainID,
Sender: sender.String(),
Asset: asset,
Amount: math.NewUint(42),
}},
)
require.NoError(t, err)
balance, err = zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender)
require.NoError(t, err)
require.Equal(t, uint64(84), balance.Uint64())
})

t.Run("should fail with invalid cctx", func(t *testing.T) {
k, ctx, _, _ := keepertest.CrosschainKeeper(t)

err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_Zeta,
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "unsupported coin type")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_Zeta,
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "unsupported coin type")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: 999999,
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "only EVM chains are supported")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: "invalid",
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "invalid sender address")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: sample.EthAddress().String(),
Amount: math.Uint{},
}},
)
require.ErrorContains(t, err, "no amount to refund")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: sample.EthAddress().String(),
Amount: math.ZeroUint(),
}},
)
require.ErrorContains(t, err, "no amount to refund")

// the foreign coin has not been set
err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: sample.EthAddress().String(),
Asset: sample.EthAddress().String(),
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "zrc not found")
})
}

func TestGetRevertGasLimit(t *testing.T) {
t.Run("should return 0 if no inbound tx params", func(t *testing.T) {
k, ctx, _, _ := keepertest.CrosschainKeeper(t)
Expand Down
4 changes: 2 additions & 2 deletions x/crosschain/keeper/msg_server_vote_inbound_tx.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,6 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg
// gas payment for erc20 type might fail because no liquidity pool is defined to swap the zrc20 token into the gas token
// in this gas we should refund the sender on ZetaChain
if cctx.InboundTxParams.CoinType == common.CoinType_ERC20 {

if err := k.RefundAbortedAmountOnZetaChain(ctx, cctx); err != nil {
// log the error
k.Logger(ctx).Error("failed to refund amount of aborted cctx on ZetaChain",
Expand All @@ -202,8 +201,9 @@ func (k msgServer) VoteOnObservedInboundTx(goCtx context.Context, msg *types.Msg
"amount", cctx.InboundTxParams.Amount.String(),
)
}
cctx.IsRefunded = true
}
cctx.IsRefunded = true

cctx.CctxStatus.ChangeStatus(types.CctxStatus_Aborted, err.Error()+" deposit revert message: "+revertMessage)
return &types.MsgVoteOnObservedInboundTxResponse{}, nil
}
Expand Down
2 changes: 1 addition & 1 deletion x/crosschain/keeper/refund.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ func (k Keeper) RefundAmountOnZetaChainGas(ctx sdk.Context, cctx types.CrossChai
if zrc20 == (ethcommon.Address{}) {
return cosmoserrors.Wrapf(types.ErrForeignCoinNotFound, "zrc20 contract address not found for chain %d", chainID)
}
// deposit the amount to the tx orgin instead of receiver as this is a refund
// deposit the amount to the tx origin instead of receiver as this is a refund
if _, err := k.fungibleKeeper.DepositZRC20(ctx, zrc20, refundTo, amountOfGasTokenLocked.BigInt()); err != nil {
return errors.New("failed to refund zeta on ZetaChain" + err.Error())
}
Expand Down
189 changes: 189 additions & 0 deletions x/crosschain/keeper/refund_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,189 @@
package keeper_test

import (
"fmt"
"testing"

"cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
"github.com/stretchr/testify/require"
"github.com/zeta-chain/zetacore/cmd/zetacored/config"
"github.com/zeta-chain/zetacore/common"
keepertest "github.com/zeta-chain/zetacore/testutil/keeper"
"github.com/zeta-chain/zetacore/testutil/sample"
"github.com/zeta-chain/zetacore/x/crosschain/types"
fungibletypes "github.com/zeta-chain/zetacore/x/fungible/types"
)

func TestKeeper_RefundAmountOnZetaChainGas(t *testing.T) {
t.Run("should refund amount zrc20 gas on zeta chain", func(t *testing.T) {
k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t)
k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName)
sender := sample.EthAddress()
chainID := getValidEthChainID(t)
deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper)
zrc20 := setupGasCoin(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper, chainID, "foobar", "foobar")

err := k.RefundAmountOnZetaChainGas(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_Gas,
SenderChainId: chainID,
Sender: sender.String(),
TxOrigin: sender.String(),
Amount: math.NewUint(42),
}},
)
require.NoError(t, err)
balance, err := zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20, sender)
require.NoError(t, err)
require.Equal(t, uint64(42), balance.Uint64())
})
}

func TestKeeper_RefundAmountOnZetaChainZeta(t *testing.T) {
t.Run("should refund amount on zeta chain", func(t *testing.T) {
k, ctx, sdkk, _ := keepertest.CrosschainKeeper(t)
k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName)
sender := sample.EthAddress()
chainID := getValidEthChainID(t)

err := k.RefundAmountOnZetaChainZeta(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_Gas,
SenderChainId: chainID,
Sender: sender.String(),
TxOrigin: sender.String(),
Amount: math.NewUint(42),
}},
)
require.NoError(t, err)
coin := sdkk.BankKeeper.GetBalance(ctx, sdk.AccAddress(sender.Bytes()), config.BaseDenom)
fmt.Println(coin.Amount.String())
require.Equal(t, "42", coin.Amount.String())
})
}

func TestKeeper_RefundAmountOnZetaChainERC20(t *testing.T) {
t.Run("should refund amount on zeta chain", func(t *testing.T) {
k, ctx, sdkk, zk := keepertest.CrosschainKeeper(t)
k.GetAuthKeeper().GetModuleAccount(ctx, fungibletypes.ModuleName)
asset := sample.EthAddress().String()
sender := sample.EthAddress()
chainID := getValidEthChainID(t)

// deploy zrc20
deploySystemContracts(t, ctx, zk.FungibleKeeper, sdkk.EvmKeeper)
zrc20Addr := deployZRC20(
t,
ctx,
zk.FungibleKeeper,
sdkk.EvmKeeper,
chainID,
"bar",
asset,
"bar",
)

err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: chainID,
Sender: sender.String(),
Asset: asset,
Amount: math.NewUint(42),
}},
)
require.NoError(t, err)

// check amount deposited in balance
balance, err := zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender)
require.NoError(t, err)
require.Equal(t, uint64(42), balance.Uint64())

// can refund again
err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: chainID,
Sender: sender.String(),
Asset: asset,
Amount: math.NewUint(42),
}},
)
require.NoError(t, err)
balance, err = zk.FungibleKeeper.BalanceOfZRC4(ctx, zrc20Addr, sender)
require.NoError(t, err)
require.Equal(t, uint64(84), balance.Uint64())
})

t.Run("should fail with invalid cctx", func(t *testing.T) {
k, ctx, _, _ := keepertest.CrosschainKeeper(t)

err := k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_Zeta,
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "unsupported coin type")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_Zeta,
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "unsupported coin type")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: 999999,
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "only EVM chains are supported")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: "invalid",
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "invalid sender address")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: sample.EthAddress().String(),
Amount: math.Uint{},
}},
)
require.ErrorContains(t, err, "no amount to refund")

err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: sample.EthAddress().String(),
Amount: math.ZeroUint(),
}},
)
require.ErrorContains(t, err, "no amount to refund")

// the foreign coin has not been set
err = k.RefundAmountOnZetaChainERC20(ctx, types.CrossChainTx{
InboundTxParams: &types.InboundTxParams{
CoinType: common.CoinType_ERC20,
SenderChainId: getValidEthChainID(t),
Sender: sample.EthAddress().String(),
Asset: sample.EthAddress().String(),
Amount: math.NewUint(42),
}},
)
require.ErrorContains(t, err, "zrc not found")
})
}

0 comments on commit e5e1bbd

Please sign in to comment.