diff --git a/x/crosschain/keeper/v2_zevm_inbound.go b/x/crosschain/keeper/v2_zevm_inbound.go index 16da9019a3..5d240de2cc 100644 --- a/x/crosschain/keeper/v2_zevm_inbound.go +++ b/x/crosschain/keeper/v2_zevm_inbound.go @@ -265,6 +265,13 @@ func (k Keeper) getZRC20InboundDetails( ctx.Logger().Info(fmt.Sprintf("cannot find foreign coin associated to the zrc20 address %s", zrc20.Hex())) return InboundDetails{}, nil } + if foreignCoin.Paused { + return InboundDetails{}, errorsmod.Wrapf( + fungibletypes.ErrPausedZRC20, + "zrc20 %s is paused", + zrc20.Hex(), + ) + } receiverChain, found := k.zetaObserverKeeper.GetSupportedChainFromChainID(ctx, foreignCoin.ForeignChainId) if !found { diff --git a/x/crosschain/keeper/v2_zevm_inbound_test.go b/x/crosschain/keeper/v2_zevm_inbound_test.go index b9673e49c6..596381c56e 100644 --- a/x/crosschain/keeper/v2_zevm_inbound_test.go +++ b/x/crosschain/keeper/v2_zevm_inbound_test.go @@ -254,6 +254,35 @@ func TestKeeper_GetErc20InboundDetails(t *testing.T) { require.Empty(t, result) }) + t.Run("fail when foreign coin is paused", func(t *testing.T) { + // ARRANGE + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + zrc20 := sample.EthAddress() + callEvent := false + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + foreignCoin := fungibletypes.ForeignCoins{ + Zrc20ContractAddress: zrc20.Hex(), + Asset: "USDT", + ForeignChainId: 1, + CoinType: coin.CoinType_ERC20, + Paused: true, + } + fungibleMock.On("GetForeignCoins", ctx, zrc20.Hex()).Return(foreignCoin, true) + + // ACT + result, err := k.GetERC20InboundDetails(ctx, zrc20, callEvent) + + // ASSERT + require.Error(t, err) + require.ErrorIs(t, err, fungibletypes.ErrPausedZRC20) + require.Contains(t, err.Error(), "zrc20 "+zrc20.Hex()+" is paused") + require.Empty(t, result) + }) + t.Run("fail when chain is not supported", func(t *testing.T) { // ARRANGE k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ @@ -322,6 +351,35 @@ func TestKeeper_GetErc20InboundDetails(t *testing.T) { require.Contains(t, err.Error(), "gas limit query failed") }) + t.Run("fail when foreign coin is paused for call event", func(t *testing.T) { + // ARRANGE + k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{ + UseFungibleMock: true, + }) + + zrc20 := sample.EthAddress() + callEvent := true + + fungibleMock := keepertest.GetCrosschainFungibleMock(t, k) + foreignCoin := fungibletypes.ForeignCoins{ + Zrc20ContractAddress: zrc20.Hex(), + Asset: "USDT", + ForeignChainId: 1, + CoinType: coin.CoinType_ERC20, + Paused: true, + } + fungibleMock.On("GetForeignCoins", ctx, zrc20.Hex()).Return(foreignCoin, true) + + // ACT + result, err := k.GetERC20InboundDetails(ctx, zrc20, callEvent) + + // ASSERT + require.Error(t, err) + require.ErrorIs(t, err, fungibletypes.ErrPausedZRC20) + require.Contains(t, err.Error(), "zrc20 "+zrc20.Hex()+" is paused") + require.Empty(t, result) + }) + t.Run("success with call event (NoAssetCall)", func(t *testing.T) { // ARRANGE k, ctx, _, _ := keepertest.CrosschainKeeperWithMocks(t, keepertest.CrosschainMockOptions{