diff --git a/x/uibc/ics20.go b/x/uibc/ics20.go index 221e8bc7e0..515b773a74 100644 --- a/x/uibc/ics20.go +++ b/x/uibc/ics20.go @@ -3,9 +3,37 @@ package uibc import ( "github.com/cosmos/cosmos-sdk/codec/types" "github.com/cosmos/cosmos-sdk/types/tx" + ics20types "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ) // UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces func (m ICS20Memo) UnpackInterfaces(unpacker types.AnyUnpacker) error { return tx.UnpackInterfaces(unpacker, m.Messages) } + +// ExtractDenomFromPacketOnRecv takes a packet with a valid ICS20 token data in the Data field +// and returns the denom as represented in the local chain. +func ExtractDenomFromPacketOnRecv(packet ibcexported.PacketI, denom string) string { + if ics20types.ReceiverChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), denom) { + // if we receive back a token, that was originally sent from UMEE, then we need to remove + // prefix added by the sender chain: port/channel/base_denom -> base_denom. + + voucherPrefix := ics20types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) + unprefixedDenom := denom[len(voucherPrefix):] + + // coin denomination used in sending from the escrow address + denom = unprefixedDenom + + // The denomination used to send the coins is either the native denom or the hash of the path + // if the denomination is not native. + denomTrace := ics20types.ParseDenomTrace(unprefixedDenom) + if !denomTrace.IsNativeDenom() { + denom = denomTrace.IBCDenom() + } + } else { + prefixedDenom := ics20types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) + denom + denom = ics20types.ParseDenomTrace(prefixedDenom).IBCDenom() + } + return denom +} diff --git a/x/uibc/quota/quota.go b/x/uibc/quota/quota.go index 0636bb3dd4..d11252a0c0 100644 --- a/x/uibc/quota/quota.go +++ b/x/uibc/quota/quota.go @@ -6,7 +6,6 @@ import ( sdkmath "cosmossdk.io/math" sdk "github.com/cosmos/cosmos-sdk/types" - ics20types "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" channeltypes "github.com/cosmos/ibc-go/v7/modules/core/04-channel/types" "github.com/cosmos/ibc-go/v7/modules/core/exported" @@ -231,30 +230,7 @@ func (k Keeper) UndoUpdateQuota(denom string, amount sdkmath.Int) error { // RecordIBCInflow will save the inflow amount if token is registered otherwise it will skip func (k Keeper) RecordIBCInflow(packet channeltypes.Packet, denom, amount string, ) exported.Acknowledgement { - // if chain is recevier and sender chain is source then we need create ibc_denom (ibc/hash(channel,denom)). - if ics20types.SenderChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), denom) { - // SendPacket did not prefix the denom, so we must prefix denom here - // NOTE: sourcePrefix already contains the trailing "/" - sourcePrefix := ics20types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel()) - prefixedDenom := sourcePrefix + denom - denom = ics20types.ParseDenomTrace(prefixedDenom).IBCDenom() - } else { - // if we receive back a token, that was originally sent from UMEE, then we need to fetch the native denom - // receive denom(port/channel/base_denom) to base_denom - - // remove prefix added by the sender chain - voucherPrefix := ics20types.GetDenomPrefix(packet.GetSourcePort(), packet.GetSourceChannel()) - unprefixedDenom := denom[len(voucherPrefix):] - // coin denomination used in sending from the escrow address - denom = unprefixedDenom - // The denomination used to send the coins is either the native denom or the hash of the path - // if the denomination is not native. - denomTrace := ics20types.ParseDenomTrace(unprefixedDenom) - if !denomTrace.IsNativeDenom() { - denom = denomTrace.IBCDenom() - } - } - + denom = uibc.ExtractDenomFromPacketOnRecv(packet, denom) ts, err := k.leverage.GetTokenSettings(*k.ctx, denom) if err != nil { if ltypes.ErrNotRegisteredToken.Is(err) { diff --git a/x/uibc/uics20/ibc_module.go b/x/uibc/uics20/ibc_module.go index e369905755..20f9fdd829 100644 --- a/x/uibc/uics20/ibc_module.go +++ b/x/uibc/uics20/ibc_module.go @@ -57,7 +57,7 @@ func (im ICS20Module) OnRecvPacket(ctx sdk.Context, packet channeltypes.Packet, if ftData.Memo != "" { logger := recvPacketLogger(&ctx) mh := MemoHandler{im.cdc, im.leverage} - if err := mh.onRecvPacket(&ctx, ftData); err != nil { + if err := mh.onRecvPacket(&ctx, packet, ftData); err != nil { logger.Error("can't handle ICS20 memo", "err", err) } } diff --git a/x/uibc/uics20/memo_handler.go b/x/uibc/uics20/memo_handler.go index 2f1e797417..c2832c575f 100644 --- a/x/uibc/uics20/memo_handler.go +++ b/x/uibc/uics20/memo_handler.go @@ -9,6 +9,7 @@ import ( sdk "github.com/cosmos/cosmos-sdk/types" "github.com/cosmos/cosmos-sdk/types/tx" ics20types "github.com/cosmos/ibc-go/v7/modules/apps/transfer/types" + ibcexported "github.com/cosmos/ibc-go/v7/modules/core/exported" ltypes "github.com/umee-network/umee/v6/x/leverage/types" "github.com/umee-network/umee/v6/x/uibc" @@ -19,7 +20,10 @@ type MemoHandler struct { leverage ltypes.MsgServer } -func (mh MemoHandler) onRecvPacket(ctx *sdk.Context, ftData ics20types.FungibleTokenPacketData) error { +func (mh MemoHandler) onRecvPacket( + ctx *sdk.Context, packet ibcexported.PacketI, ftData ics20types.FungibleTokenPacketData, +) error { + msgs, err := deserializeMemoMsgs(mh.cdc, []byte(ftData.Memo)) if err != nil { recvPacketLogger(ctx).Debug("Can't deserialize ICS20 memo for hook execution", "err", err) @@ -36,7 +40,8 @@ func (mh MemoHandler) onRecvPacket(ctx *sdk.Context, ftData ics20types.FungibleT if !ok { return fmt.Errorf("can't parse transfer amount: %s [%w]", ftData.Amount, err) } - return mh.dispatchMemoMsgs(ctx, receiver, sdk.NewCoin(ftData.Denom, amount), msgs) + ibcDenom := uibc.ExtractDenomFromPacketOnRecv(packet, ftData.Denom) + return mh.dispatchMemoMsgs(ctx, receiver, sdk.NewCoin(ibcDenom, amount), msgs) } // runs messages encoded in the ICS20 memo.