From 02c98c3824f714c3af17e2fb2590ed317835238d Mon Sep 17 00:00:00 2001 From: Dan Kanefsky <56059752+boojamya@users.noreply.github.com> Date: Tue, 15 Nov 2022 17:47:59 -0800 Subject: [PATCH] Add blockibc middleware to the tokenfactory (#41) --- app/app.go | 7 +- x/tokenfactory/blockibc_middleware.go | 125 ++++++++++++++++++++++++++ 2 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 x/tokenfactory/blockibc_middleware.go diff --git a/app/app.go b/app/app.go index 543a8e79..94a5a424 100644 --- a/app/app.go +++ b/app/app.go @@ -364,8 +364,11 @@ func New( app.BankKeeper, scopedTransferKeeper, ) + + var transferStack ibcporttypes.IBCModule transferModule := transfer.NewAppModule(app.TransferKeeper) - transferIBCModule := transfer.NewIBCModule(app.TransferKeeper) + transferStack = transfer.NewIBCModule(app.TransferKeeper) + transferStack = tokenfactorymodule.NewIBCMiddleware(transferStack, app.TokenfactoryKeeper) app.ICAHostKeeper = icahostkeeper.NewKeeper( appCodec, keys[icahosttypes.StoreKey], @@ -439,7 +442,7 @@ func New( // Create static IBC router, add transfer route, then set and seal it ibcRouter := ibcporttypes.NewRouter() ibcRouter.AddRoute(icahosttypes.SubModuleName, icaHostIBCModule). - AddRoute(ibctransfertypes.ModuleName, transferIBCModule). + AddRoute(ibctransfertypes.ModuleName, transferStack). AddRoute(ccvconsumertypes.ModuleName, consumerModule) // this line is used by starport scaffolding # ibc/app/router app.IBCKeeper.SetRouter(ibcRouter) diff --git a/x/tokenfactory/blockibc_middleware.go b/x/tokenfactory/blockibc_middleware.go new file mode 100644 index 00000000..dd656af3 --- /dev/null +++ b/x/tokenfactory/blockibc_middleware.go @@ -0,0 +1,125 @@ +package tokenfactory + +import ( + sdk "github.com/cosmos/cosmos-sdk/types" + sdkerrors "github.com/cosmos/cosmos-sdk/types/errors" + capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types" + transfertypes "github.com/cosmos/ibc-go/v3/modules/apps/transfer/types" + channeltypes "github.com/cosmos/ibc-go/v3/modules/core/04-channel/types" + porttypes "github.com/cosmos/ibc-go/v3/modules/core/05-port/types" + ibcexported "github.com/cosmos/ibc-go/v3/modules/core/exported" + "github.com/strangelove-ventures/noble/x/tokenfactory/keeper" + "github.com/strangelove-ventures/noble/x/tokenfactory/types" +) + +var _ porttypes.IBCModule = &IBCMiddleware{} + +// IBCMiddleware implements the tokenfactory keeper in order to check againset blacklisted addresses. +type IBCMiddleware struct { + app porttypes.IBCModule + keeper keeper.Keeper +} + +// NewIBCMiddleware creates a new IBCMiddleware given the keeper and underlying application. +func NewIBCMiddleware(app porttypes.IBCModule, k keeper.Keeper) IBCMiddleware { + return IBCMiddleware{ + app: app, + keeper: k, + } +} + +// OnChanOpenInit implements the IBCModule interface. +func (im IBCMiddleware) OnChanOpenInit( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID string, + channelID string, + channelCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + version string, +) error { + return im.app.OnChanOpenInit(ctx, order, connectionHops, portID, channelID, channelCap, counterparty, version) +} + +// OnChanOpenTry implements the IBCModule interface. +func (im IBCMiddleware) OnChanOpenTry( + ctx sdk.Context, + order channeltypes.Order, + connectionHops []string, + portID, channelID string, + chanCap *capabilitytypes.Capability, + counterparty channeltypes.Counterparty, + counterpartyVersion string, +) (version string, err error) { + return im.app.OnChanOpenTry(ctx, order, connectionHops, portID, channelID, chanCap, counterparty, counterpartyVersion) +} + +// OnChanOpenAck implements the IBCModule interface. +func (im IBCMiddleware) OnChanOpenAck( + ctx sdk.Context, + portID, channelID string, + counterpartyChannelID string, + counterpartyVersion string, +) error { + return im.app.OnChanOpenAck(ctx, portID, channelID, counterpartyChannelID, counterpartyVersion) +} + +// OnChanOpenConfirm implements the IBCModule interface. +func (im IBCMiddleware) OnChanOpenConfirm(ctx sdk.Context, portID, channelID string) error { + return im.app.OnChanOpenConfirm(ctx, portID, channelID) +} + +// OnChanCloseInit implements the IBCModule interface. +func (im IBCMiddleware) OnChanCloseInit(ctx sdk.Context, portID, channelID string) error { + return im.app.OnChanCloseInit(ctx, portID, channelID) +} + +// OnChanCloseConfirm implements the IBCModule interface. +func (im IBCMiddleware) OnChanCloseConfirm(ctx sdk.Context, portID, channelID string) error { + return im.app.OnChanCloseConfirm(ctx, portID, channelID) +} + +// OnRecvPacket intercepts the packet data and checks the the sender and receiver address against +// the blacklisted addresses held in the tokenfactory keeper. If the address is found in the blacklist, an +// acknoledgmet error is returned. +func (im IBCMiddleware) OnRecvPacket( + ctx sdk.Context, + packet channeltypes.Packet, + relayer sdk.AccAddress, +) ibcexported.Acknowledgement { + + var data transfertypes.FungibleTokenPacketData + var ackErr error + if err := types.ModuleCdc.UnmarshalJSON(packet.GetData(), &data); err != nil { + ackErr = sdkerrors.Wrapf(sdkerrors.ErrInvalidType, "cannot unmarshal ICS-20 transfer packet data") + return channeltypes.NewErrorAcknowledgement(ackErr.Error()) + } + _, found := im.keeper.GetBlacklisted(ctx, data.Receiver) + if found { + ackErr = sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "receiver address is blacklisted") + return channeltypes.NewErrorAcknowledgement(ackErr.Error()) + } + + _, found = im.keeper.GetBlacklisted(ctx, data.Sender) + if found { + ackErr = sdkerrors.Wrapf(sdkerrors.ErrUnauthorized, "sender address is blacklisted") + return channeltypes.NewErrorAcknowledgement(ackErr.Error()) + } + return im.app.OnRecvPacket(ctx, packet, relayer) +} + +// OnAcknowledgementPacket implements the IBCModule interface. +func (im IBCMiddleware) OnAcknowledgementPacket( + ctx sdk.Context, + packet channeltypes.Packet, + acknowledgement []byte, + relayer sdk.AccAddress, +) error { + return im.app.OnAcknowledgementPacket(ctx, packet, acknowledgement, relayer) +} + +// OnTimeoutPacket implements the IBCModule interface. +func (im IBCMiddleware) OnTimeoutPacket(ctx sdk.Context, packet channeltypes.Packet, relayer sdk.AccAddress) error { + return im.app.OnTimeoutPacket(ctx, packet, relayer) +}