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

feat(uibc): adding ICS 20 memo handler #2349

Merged
merged 10 commits into from
Dec 18, 2023
16 changes: 16 additions & 0 deletions proto/umee/uibc/v1/uibc.proto
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
syntax = "proto3";
package umee.uibc.v1;

import "cosmos_proto/cosmos.proto";

Check failure on line 4 in proto/umee/uibc/v1/uibc.proto

View workflow job for this annotation

GitHub Actions / buf-lint

Import "cosmos_proto/cosmos.proto" is unused.
import "gogoproto/gogo.proto";
import "google/protobuf/any.proto";

option go_package = "github.com/umee-network/umee/v6/x/uibc";

option (gogoproto.goproto_getters_all) = false;
option (gogoproto.messagename_all) = true;

message ICS20Memo {

Check failure on line 13 in proto/umee/uibc/v1/uibc.proto

View workflow job for this annotation

GitHub Actions / buf-lint

Message "ICS20Memo" should have a non-empty comment for documentation.
// messages is a list of `sdk.Msg`s that will be executed when handling ICS20 transfer.
repeated google.protobuf.Any messages = 1;
}
11 changes: 11 additions & 0 deletions x/uibc/ics20.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package uibc

import (
"github.com/cosmos/cosmos-sdk/codec/types"
"github.com/cosmos/cosmos-sdk/types/tx"
)

// UnpackInterfaces implements UnpackInterfacesMessage.UnpackInterfaces
func (m ICS20Memo) UnpackInterfaces(unpacker types.AnyUnpacker) error {
return tx.UnpackInterfaces(unpacker, m.Messages)
}
12 changes: 2 additions & 10 deletions x/uibc/quota/ibc_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import (

func (k Keeper) IBCOnSendPacket(packet []byte) error {
params := k.GetParams()

if !params.IbcStatus.IBCTransferEnabled() {
return ics20types.ErrSendDisabled
}
Expand All @@ -34,21 +33,14 @@ func (k Keeper) IBCOnSendPacket(packet []byte) error {
return nil
}

func (k Keeper) IBCOnRecvPacket(packet channeltypes.Packet) exported.Acknowledgement {
func (k Keeper) IBCOnRecvPacket(ft ics20types.FungibleTokenPacketData, packet channeltypes.Packet) exported.Acknowledgement {
params := k.GetParams()
if !params.IbcStatus.IBCTransferEnabled() {
return channeltypes.NewErrorAcknowledgement(ics20types.ErrReceiveDisabled)
}

if params.IbcStatus.OutflowQuotaEnabled() {
var data ics20types.FungibleTokenPacketData
if err := ics20types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil {
ackErr := sdkerrors.ErrInvalidType.Wrap("cannot unmarshal ICS-20 transfer packet data")
return channeltypes.NewErrorAcknowledgement(ackErr)
}

isSourceChain := ics20types.SenderChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), data.Denom)
ackErr := k.RecordIBCInflow(packet, data.Denom, data.Amount, isSourceChain)
ackErr := k.RecordIBCInflow(packet, ft.Denom, ft.Amount)
if ackErr != nil {
return ackErr
}
Expand Down
21 changes: 11 additions & 10 deletions x/uibc/quota/quota.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import (

sdkmath "cosmossdk.io/math"
sdk "github.com/cosmos/cosmos-sdk/types"
transfertypes "github.com/cosmos/ibc-go/v7/modules/apps/transfer/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"

Expand Down Expand Up @@ -229,24 +229,25 @@ 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, dataDenom, dataAmount string, isSourceChain bool,
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)) to
// check ibc_denom is exists in leverage token registry
if isSourceChain {
if !ics20types.SenderChainIsSource(packet.GetSourcePort(), packet.GetSourceChannel(), denom) {
// since SendPacket did not prefix the denomination, we must prefix denomination here
sourcePrefix := transfertypes.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel())
sourcePrefix := ics20types.GetDenomPrefix(packet.GetDestPort(), packet.GetDestChannel())
// NOTE: sourcePrefix contains the trailing "/"
prefixedDenom := sourcePrefix + dataDenom
prefixedDenom := sourcePrefix + denom
// construct the denomination trace from the full raw denomination and get the ibc_denom
ibcDenom := transfertypes.ParseDenomTrace(prefixedDenom).IBCDenom()
ibcDenom := ics20types.ParseDenomTrace(prefixedDenom).IBCDenom()
ts, err := k.leverage.GetTokenSettings(*k.ctx, ibcDenom)
if err != nil {
// skip if token is not a registered token on leverage
if ltypes.ErrNotRegisteredToken.Is(err) {
return nil
return nil // skip recording inflow if the token is not registered
}
k.ctx.Logger().Error("can't get x/leverage token settings", "error", err)
return channeltypes.NewErrorAcknowledgement(err)
}

// get the exchange price (eg: UMEE) in USD from oracle using SYMBOL Denom eg: `UMEE`
Expand All @@ -256,7 +257,7 @@ func (k Keeper) RecordIBCInflow(
}
// calculate total exchange rate
powerReduction := ten.Power(uint64(ts.Exponent))
inflowInUSD := sdk.MustNewDecFromStr(dataAmount).Quo(powerReduction).Mul(exchangeRate)
inflowInUSD := sdk.MustNewDecFromStr(amount).Quo(powerReduction).Mul(exchangeRate)

tokenInflow := sdk.NewDecCoinFromDec(ibcDenom, inflowInUSD)
k.SetTokenInflow(tokenInflow)
Expand Down
Loading
Loading