Skip to content

Commit

Permalink
feat(ibc transfer): Register IBC denom on transfer (#900)
Browse files Browse the repository at this point in the history
Co-authored-by: Michael Tsitrin <michael@dymension.xyz>
  • Loading branch information
zale144 and mtsitrin authored Jun 11, 2024
1 parent c3d9307 commit 78494bd
Show file tree
Hide file tree
Showing 26 changed files with 1,076 additions and 218 deletions.
3 changes: 2 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Ref: https://keepachangelog.com/en/1.0.0/

### Features

- (denommetadata) [#907](https://github.com/dymensionxyz/dymension/issues/907) Add IBC middleware to migrate denom metadata to rollappp, remove `CreateDenomMetadata` and `UpdateDenomMetadata` tx handlers
- (delayedack) [#849](https://github.com/dymensionxyz/dymension/issues/849) Add demand order filters: type, rollapp id and limit
- (delayedack) [#850](https://github.com/dymensionxyz/dymension/issues/850) Add type filter for delayedack
- (rollapp) [#829](https://github.com/dymensionxyz/dymension/issues/829) Refactor rollapp cli to be more useful
Expand Down Expand Up @@ -81,7 +82,7 @@ Ref: https://keepachangelog.com/en/1.0.0/
- (rollapp) [#839](https://github.com/dymensionxyz/dymension/issues/839) Remove rollapp deprecated fields
- (eibc) [#836](https://github.com/dymensionxyz/dymension/issues/836) Improve eibc memo error handling
- (eibc) [#830](https://github.com/dymensionxyz/dymension/issues/830) Invalid tx should return ackErr
- (eibc) [#828](https://github.com/dymensionxyz/dymension/issues/828) Wrong packet written on delayedack acknowledgment
- (eibc) [#828](https://github.com/dymensionxyz/dymension/issues/828) Wrong packet written on delayedack acknowledgement
- (delayedack) [#822](https://github.com/dymensionxyz/dymension/issues/822) Acknowledgement not written in case of ackerr
- (rollapp) [#820](https://github.com/dymensionxyz/dymension/issues/820) Invariant block-height-to-finalization-queue fix for freezing rollapp
- (delayedack) [#814](https://github.com/dymensionxyz/dymension/issues/814) Proof height ante handler doesn't gurantee uniqueness
Expand Down
54 changes: 32 additions & 22 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"github.com/cosmos/cosmos-sdk/server/api"
"github.com/cosmos/cosmos-sdk/server/config"
servertypes "github.com/cosmos/cosmos-sdk/server/types"
simapp "github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/simapp"
"github.com/cosmos/cosmos-sdk/store/streaming"

storetypes "github.com/cosmos/cosmos-sdk/store/types"
Expand Down Expand Up @@ -110,7 +110,7 @@ import (

simappparams "github.com/cosmos/cosmos-sdk/simapp/params"

ante "github.com/dymensionxyz/dymension/v3/app/ante"
"github.com/dymensionxyz/dymension/v3/app/ante"
appparams "github.com/dymensionxyz/dymension/v3/app/params"

rollappmodule "github.com/dymensionxyz/dymension/v3/x/rollapp"
Expand Down Expand Up @@ -144,6 +144,8 @@ import (
packetforwardkeeper "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6/packetforward/keeper"
packetforwardtypes "github.com/cosmos/ibc-apps/middleware/packet-forward-middleware/v6/packetforward/types"

"github.com/dymensionxyz/dymension/v3/x/transferinject"

/* ------------------------------ ethermint imports ----------------------------- */

"github.com/evmos/ethermint/ethereum/eip712"
Expand Down Expand Up @@ -171,14 +173,14 @@ import (
"github.com/osmosis-labs/osmosis/v15/x/gamm"
gammkeeper "github.com/osmosis-labs/osmosis/v15/x/gamm/keeper"
gammtypes "github.com/osmosis-labs/osmosis/v15/x/gamm/types"
incentives "github.com/osmosis-labs/osmosis/v15/x/incentives"
"github.com/osmosis-labs/osmosis/v15/x/incentives"
incentiveskeeper "github.com/osmosis-labs/osmosis/v15/x/incentives/keeper"
incentivestypes "github.com/osmosis-labs/osmosis/v15/x/incentives/types"
"github.com/osmosis-labs/osmosis/v15/x/poolmanager"
poolmanagerkeeper "github.com/osmosis-labs/osmosis/v15/x/poolmanager/keeper"
poolmanagertypes "github.com/osmosis-labs/osmosis/v15/x/poolmanager/types"

txfees "github.com/osmosis-labs/osmosis/v15/x/txfees"
"github.com/osmosis-labs/osmosis/v15/x/txfees"
txfeeskeeper "github.com/osmosis-labs/osmosis/v15/x/txfees/keeper"
txfeestypes "github.com/osmosis-labs/osmosis/v15/x/txfees/types"

Expand Down Expand Up @@ -597,19 +599,6 @@ func New(
nil,
)

// Create Transfer Keepers
app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec,
keys[ibctransfertypes.StoreKey],
app.GetSubspace(ibctransfertypes.ModuleName),
app.IBCKeeper.ChannelKeeper,
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
app.AccountKeeper,
app.BankKeeper,
scopedTransferKeeper,
)

app.DenomMetadataKeeper = denommetadatamodulekeeper.NewKeeper(
app.BankKeeper,
)
Expand All @@ -626,18 +615,31 @@ func New(
keys[rollappmoduletypes.MemStoreKey],
app.GetSubspace(rollappmoduletypes.ModuleName),
app.IBCKeeper.ClientKeeper,
app.TransferKeeper,
app.IBCKeeper.ChannelKeeper,
app.BankKeeper,
app.DenomMetadataKeeper,
)

// Create Transfer Keepers
app.TransferKeeper = ibctransferkeeper.NewKeeper(
appCodec,
keys[ibctransfertypes.StoreKey],
app.GetSubspace(ibctransfertypes.ModuleName),
transferinject.NewIBCSendMiddleware(app.IBCKeeper.ChannelKeeper, app.RollappKeeper, app.BankKeeper),
app.IBCKeeper.ChannelKeeper,
&app.IBCKeeper.PortKeeper,
app.AccountKeeper,
app.BankKeeper,
scopedTransferKeeper,
)

app.RollappKeeper.SetTransferKeeper(app.TransferKeeper)

app.SequencerKeeper = *sequencermodulekeeper.NewKeeper(
appCodec,
keys[sequencermoduletypes.StoreKey],
keys[sequencermoduletypes.MemStoreKey],
app.GetSubspace(sequencermoduletypes.ModuleName),

app.BankKeeper,
app.RollappKeeper,
)
Expand Down Expand Up @@ -743,7 +745,14 @@ func New(
transferMiddleware := ibctransfer.NewIBCModule(app.TransferKeeper)

var transferStack ibcporttypes.IBCModule
transferStack = bridging_fee.NewIBCMiddleware(transferMiddleware, app.IBCKeeper.ChannelKeeper, app.DelayedAckKeeper, app.TransferKeeper, app.AccountKeeper.GetModuleAddress(txfeestypes.ModuleName))
transferStack = bridging_fee.NewIBCMiddleware(
transferMiddleware,
app.IBCKeeper.ChannelKeeper,
app.DelayedAckKeeper,
app.RollappKeeper,
app.TransferKeeper,
app.AccountKeeper.GetModuleAddress(txfeestypes.ModuleName),
)

transferStack = packetforwardmiddleware.NewIBCMiddleware(
transferStack,
Expand All @@ -752,7 +761,8 @@ func New(
packetforwardkeeper.DefaultForwardTransferPacketTimeoutTimestamp,
packetforwardkeeper.DefaultRefundTransferPacketTimeoutTimestamp,
)
transferStack = delayedackmodule.NewIBCMiddleware(transferStack, app.DelayedAckKeeper)
delayedAckMiddleware := delayedackmodule.NewIBCMiddleware(transferStack, app.DelayedAckKeeper, app.RollappKeeper)
transferStack = transferinject.NewIBCAckMiddleware(delayedAckMiddleware, app.RollappKeeper)

// Create static IBC router, add transfer route, then set and seal it
ibcRouter := ibcporttypes.NewRouter()
Expand All @@ -764,7 +774,7 @@ func New(
app.RollappKeeper.SetHooks(rollappmoduletypes.NewMultiRollappHooks(
// insert rollapp hooks receivers here
app.SequencerKeeper.RollappHooks(),
transferStack.(delayedackmodule.IBCMiddleware),
delayedAckMiddleware,
))

/**** Module Options ****/
Expand Down
4 changes: 4 additions & 0 deletions ibctesting/delayed_ack_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/suite"

"github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
Expand All @@ -25,6 +26,9 @@ func TestDelayedAckTestSuite(t *testing.T) {

func (suite *DelayedAckTestSuite) SetupTest() {
suite.IBCTestUtilSuite.SetupTest()
ConvertToApp(suite.hubChain).BankKeeper.SetDenomMetaData(suite.hubChain.GetContext(), banktypes.Metadata{
Base: sdk.DefaultBondDenom,
})
}

// Transfer from cosmos chain to the hub. No delay expected
Expand Down
4 changes: 4 additions & 0 deletions ibctesting/eibc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"testing"

sdk "github.com/cosmos/cosmos-sdk/types"
banktypes "github.com/cosmos/cosmos-sdk/x/bank/types"
"github.com/stretchr/testify/suite"

"github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
Expand All @@ -34,6 +35,9 @@ func TestEIBCTestSuite(t *testing.T) {

func (suite *EIBCTestSuite) SetupTest() {
suite.IBCTestUtilSuite.SetupTest()
ConvertToApp(suite.hubChain).BankKeeper.SetDenomMetaData(suite.hubChain.GetContext(), banktypes.Metadata{
Base: sdk.DefaultBondDenom,
})
eibcKeeper := ConvertToApp(suite.hubChain).EIBCKeeper
suite.msgServer = eibckeeper.NewMsgServerImpl(eibcKeeper)
// Change the delayedAck epoch to trigger every month to not
Expand Down
6 changes: 4 additions & 2 deletions ibctesting/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,15 @@ import (
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
ibctesting "github.com/cosmos/ibc-go/v6/testing"
"github.com/cosmos/ibc-go/v6/testing/mock"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

"github.com/dymensionxyz/dymension/v3/app"
"github.com/dymensionxyz/dymension/v3/app/apptesting"
common "github.com/dymensionxyz/dymension/v3/x/common/types"
eibctypes "github.com/dymensionxyz/dymension/v3/x/eibc/types"
rollappkeeper "github.com/dymensionxyz/dymension/v3/x/rollapp/keeper"
rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types"
sequencertypes "github.com/dymensionxyz/dymension/v3/x/sequencer/types"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"

"github.com/stretchr/testify/require"
"github.com/stretchr/testify/suite"
Expand Down Expand Up @@ -240,7 +242,7 @@ func (suite *IBCTestUtilSuite) NewTransferPath(chainA, chainB *ibctesting.TestCh

func (suite *IBCTestUtilSuite) GetRollappToHubIBCDenomFromPacket(packet channeltypes.Packet) string {
var data transfertypes.FungibleTokenPacketData
err := transfertypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data)
err := eibctypes.ModuleCdc.UnmarshalJSON(packet.GetData(), &data)
suite.Require().NoError(err)
return suite.GetIBCDenomForChannel(packet.GetDestChannel(), data.Denom)
}
Expand Down
2 changes: 2 additions & 0 deletions proto/dymension/rollapp/rollapp.proto
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ message Rollapp {
string channel_id = 8;
// frozen is a boolean that indicates if the rollapp is frozen.
bool frozen = 9;
// registeredDenoms is a list of registered denom bases on this rollapp
repeated string registeredDenoms = 10;
}

// Rollapp summary is a compact representation of Rollapp
Expand Down
14 changes: 10 additions & 4 deletions testutil/keeper/delayedack.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,19 +11,21 @@ import (
sdk "github.com/cosmos/cosmos-sdk/types"
capabilitytypes "github.com/cosmos/cosmos-sdk/x/capability/types"
typesparams "github.com/cosmos/cosmos-sdk/x/params/types"
transfertypes "github.com/cosmos/ibc-go/v6/modules/apps/transfer/types"
clienttypes "github.com/cosmos/ibc-go/v6/modules/core/02-client/types"
connectiontypes "github.com/cosmos/ibc-go/v6/modules/core/03-connection/types"
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
"github.com/cosmos/ibc-go/v6/modules/core/exported"
ibctypes "github.com/cosmos/ibc-go/v6/modules/light-clients/07-tendermint/types"
"github.com/dymensionxyz/dymension/v3/x/delayedack/keeper"
"github.com/dymensionxyz/dymension/v3/x/delayedack/types"
rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types"
sequencertypes "github.com/dymensionxyz/dymension/v3/x/sequencer/types"
"github.com/stretchr/testify/require"
"github.com/tendermint/tendermint/libs/log"
tmproto "github.com/tendermint/tendermint/proto/tendermint/types"
tmdb "github.com/tendermint/tm-db"

"github.com/dymensionxyz/dymension/v3/x/delayedack/keeper"
"github.com/dymensionxyz/dymension/v3/x/delayedack/types"
rollapptypes "github.com/dymensionxyz/dymension/v3/x/rollapp/types"
sequencertypes "github.com/dymensionxyz/dymension/v3/x/sequencer/types"
)

type ChannelKeeperStub struct{}
Expand Down Expand Up @@ -113,6 +115,10 @@ func (RollappKeeperStub) GetAllRollapps(ctx sdk.Context) (list []rollapptypes.Ro
return []rollapptypes.Rollapp{}
}

func (r RollappKeeperStub) ExtractRollappIDAndTransferPacketFromData(sdk.Context, []byte, string, string) (string, *transfertypes.FungibleTokenPacketData, error) {
return "rollappID", &transfertypes.FungibleTokenPacketData{}, nil
}

type SequencerKeeperStub struct{}

func (SequencerKeeperStub) GetSequencer(ctx sdk.Context, sequencerAddress string) (val sequencertypes.Sequencer, found bool) {
Expand Down
2 changes: 1 addition & 1 deletion testutil/keeper/rollapp.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
storetypes "github.com/cosmos/cosmos-sdk/store/types"
sdk "github.com/cosmos/cosmos-sdk/types"
typesparams "github.com/cosmos/cosmos-sdk/x/params/types"

"github.com/dymensionxyz/dymension/v3/x/rollapp/keeper"
"github.com/dymensionxyz/dymension/v3/x/rollapp/types"

Expand Down Expand Up @@ -46,7 +47,6 @@ func RollappKeeper(t testing.TB) (*keeper.Keeper, sdk.Context) {
nil,
nil,
nil,
nil,
)

ctx := sdk.NewContext(stateStore, tmproto.Header{}, false, log.NewNopLogger())
Expand Down
18 changes: 14 additions & 4 deletions x/bridging_fee/ibc_middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@ import (
errorsmod "cosmossdk.io/errors"
sdk "github.com/cosmos/cosmos-sdk/types"
sdkerrors "github.com/cosmos/cosmos-sdk/types/errors"
transfer "github.com/cosmos/ibc-go/v6/modules/apps/transfer"
"github.com/cosmos/ibc-go/v6/modules/apps/transfer"
transferkeeper "github.com/cosmos/ibc-go/v6/modules/apps/transfer/keeper"
channeltypes "github.com/cosmos/ibc-go/v6/modules/core/04-channel/types"
porttypes "github.com/cosmos/ibc-go/v6/modules/core/05-port/types"
"github.com/cosmos/ibc-go/v6/modules/core/exported"

delayedaackkeeper "github.com/dymensionxyz/dymension/v3/x/delayedack/keeper"
rollappkeeper "github.com/dymensionxyz/dymension/v3/x/rollapp/keeper"
)

const (
Expand All @@ -27,17 +28,26 @@ type BridgingFeeMiddleware struct {
transfer.IBCModule
porttypes.ICS4Wrapper

rollappKeeper rollappkeeper.Keeper
delayedAckKeeper delayedaackkeeper.Keeper
transferKeeper transferkeeper.Keeper
feeModuleAddr sdk.AccAddress
}

// NewIBCMiddleware creates a new IBCMiddleware given the keeper and underlying application
func NewIBCMiddleware(transfer transfer.IBCModule, channelKeeper porttypes.ICS4Wrapper, keeper delayedaackkeeper.Keeper, transferKeeper transferkeeper.Keeper, feeModuleAddr sdk.AccAddress) *BridgingFeeMiddleware {
func NewIBCMiddleware(
transfer transfer.IBCModule,
channelKeeper porttypes.ICS4Wrapper,
delayedAckKeeper delayedaackkeeper.Keeper,
rollappKeeper rollappkeeper.Keeper,
transferKeeper transferkeeper.Keeper,
feeModuleAddr sdk.AccAddress,
) *BridgingFeeMiddleware {
return &BridgingFeeMiddleware{
IBCModule: transfer,
ICS4Wrapper: channelKeeper,
delayedAckKeeper: keeper,
delayedAckKeeper: delayedAckKeeper,
rollappKeeper: rollappKeeper,
transferKeeper: transferKeeper,
feeModuleAddr: feeModuleAddr,
}
Expand All @@ -59,7 +69,7 @@ func (im *BridgingFeeMiddleware) OnRecvPacket(ctx sdk.Context, packet channeltyp
"packet_sequence", packet.Sequence)

rollappPortOnHub, rollappChannelOnHub := packet.DestinationPort, packet.DestinationChannel
rollappID, transferPacketData, err := im.delayedAckKeeper.ExtractRollappIDAndTransferPacket(ctx, packet, rollappPortOnHub, rollappChannelOnHub)
rollappID, transferPacketData, err := im.rollappKeeper.ExtractRollappIDAndTransferPacketFromData(ctx, packet.Data, rollappPortOnHub, rollappChannelOnHub)
if err != nil {
logger.Error("Failed to extract rollapp id from packet", "err", err)
return channeltypes.NewErrorAcknowledgement(err)
Expand Down
10 changes: 5 additions & 5 deletions x/delayedack/eibc.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,9 +43,9 @@ func (im IBCMiddleware) eIBCDemandOrderHandler(ctx sdk.Context, rollappPacket co
var feeMultiplier sdk.Dec
switch t {
case commontypes.RollappPacket_ON_TIMEOUT:
feeMultiplier = im.keeper.TimeoutFee(ctx)
feeMultiplier = im.TimeoutFee(ctx)
case commontypes.RollappPacket_ON_ACK:
feeMultiplier = im.keeper.ErrAckFee(ctx)
feeMultiplier = im.ErrAckFee(ctx)
}
fee := amountDec.Mul(feeMultiplier).TruncateInt()
if !fee.IsPositive() {
Expand All @@ -64,7 +64,7 @@ func (im IBCMiddleware) eIBCDemandOrderHandler(ctx sdk.Context, rollappPacket co
return fmt.Errorf("create eibc demand order: %w", err)
}

err = im.keeper.SetDemandOrder(ctx, eibcDemandOrder)
err = im.SetDemandOrder(ctx, eibcDemandOrder)
if err != nil {
return fmt.Errorf("set eibc demand order: %w", err)
}
Expand All @@ -86,7 +86,7 @@ func (im IBCMiddleware) createDemandOrderFromIBCPacket(ctx sdk.Context, fungible
return nil, fmt.Errorf("validate eibc metadata: %w", err)
}
// Verify the original recipient is not a blocked sender otherwise could potentially use eibc to bypass it
if im.keeper.BlockedAddr(fungibleTokenPacketData.Receiver) {
if im.BlockedAddr(fungibleTokenPacketData.Receiver) {
return nil, fmt.Errorf("not allowed to receive funds: receiver: %s", fungibleTokenPacketData.Receiver)
}
// Calculate the demand order price and validate it,
Expand Down Expand Up @@ -126,7 +126,7 @@ func (im IBCMiddleware) createDemandOrderFromIBCPacket(ctx sdk.Context, fungible
demandOrderDenom = trace.IBCDenom()
demandOrderRecipient = fungibleTokenPacketData.Sender // and who tried to send it (refund because it failed)
case commontypes.RollappPacket_ON_RECV:
bridgingFee := im.keeper.BridgingFeeFromAmt(ctx, amt)
bridgingFee := im.BridgingFeeFromAmt(ctx, amt)
if bridgingFee.GT(fee) {
// We check that the fee the fulfiller makes is at least as big as the bridging fee they will have to pay later
// this is to improve UX and help fulfillers not lose money.
Expand Down
Loading

0 comments on commit 78494bd

Please sign in to comment.