diff --git a/docs/docs/04-middleware/02-callbacks/01-overview.md b/docs/docs/04-middleware/02-callbacks/01-overview.md index ca469a80e79..eae194b2b96 100644 --- a/docs/docs/04-middleware/02-callbacks/01-overview.md +++ b/docs/docs/04-middleware/02-callbacks/01-overview.md @@ -49,3 +49,7 @@ And the following diagram shows how a typical `SendPacket` and `WriteAcknowledge - Maximum gas limit is hardcoded manually during wiring. It requires a coordinated upgrade to change the maximum gas limit. - The receive packet callback does not pass the relayer address to the secondary application. This is so that we can use the same callback for both synchronous and asynchronous acknowledgements. - The receive packet callback does not pass IBC Actor's address, this is because the IBC Actor lives in the counterparty chain and cannot be trusted. + +:::warning +If the callbacks middleware wraps the transfer application, we strongly discourage the usage of source callbacks if [`MsgTransfer` includes forwarding information](https://github.com/cosmos/ibc-go/blob/v9.0.0-rc.0/proto/ibc/applications/transfer/v1/tx.proto#L54-L55) (which is only supported from ICS20 v2). Source callback information will be executed on the last hop before the destination chain, not on the sending chain. The explanation for this behaviour is that, if the tokens are routed through intermediary chains, then the transfer application on the sending chain will construct a packet data where the [`memo` field](https://github.com/cosmos/ibc-go/blob/v9.0.0-rc.0/proto/ibc/applications/transfer/v2/packet.proto#L38) is empty, and any [memo string](https://github.com/cosmos/ibc-go/blob/v9.0.0-rc.0/proto/ibc/applications/transfer/v1/tx.proto#L51) included in `MsgTransfer` is placed in the [`destination_memo` field](https://github.com/cosmos/ibc-go/blob/v9.0.0-rc.0/proto/ibc/applications/transfer/v2/packet.proto#L48). This makes it impossible to trigger the source callbacks on the sending chain, since the memo string is not available in the `memo` field. Then, on the chain before the final destination chain, the transfer application will construct the packet data with the memo string back in the `memo` field, so that it can be consumed by the callbacks middleware on the destination chain. However, if the `memo` field of `FungibleTokenPacketDataV2` is not empty on the chain before the final destination and the transfer application on that chain is wrapped by callbacks middleware, then the source callbacks would be triggered. Therefore, in order to prevent this unexpected behaviour (i.e. source callbacks triggered not on sending chain, but on the intermediary chain before the final destination) we are strongly recommeding to not include source callbacks information in the `memo` field of `MsgTransfer`. +:::