Authors: @barry, @johnletey, @mag
Intro
This short blog post is about IBC (the first and only truly neutral interoperability protocol) and a couple of extraordinary but not-widely-known technologies that make IBC even more powerful:
- IBC Hooks: Allows incoming token transfers to call a function on any smart contract. This enables very expressive cross-chain workflows that users can initiate with just one transaction. (Brought to us by the fantastic folks contributing to Osmosis)
- Packet Forward Middleware (PFM): Allows an incoming IBC token transfer to trigger an outgoing transfer bound for another chain with atomic success/failure across the entire sequence. This enables atomic n-chain transfers and ensures users are always 1 transaction away from their destination (Brought to us by the fantastic folks at Strangelove)
tl;dr for the visually inclined:
We’re writing this for two audiences:
- Cosmos developers: We hope this inspires you to add support for PFM and IBC hooks to your chain (ibc-go does not have them out of the box!) and points you in the right direction to do so (ibc-apps repo is the home of both of these projects and will quickly grow to include more next-gen IBC tech) (Contact me or DM @SkipProtocol on Twitter if you need help)
- Developers in other ecosystems:* We hope this inspires you to look more into IBC and contribute to whichever ongoing ecosystem integration effort is relevant to you. Folks talk about the “Cosmosification” of Ethereum and how that’s going to hurt UX a lot. We hope this post demonstrates to you that a lot of that conversation is overblown: With standardized interop protocols we can have really great UX even when we need to manage many disparate chains. The section below on what makes IBC special is for you.
This post isn’t intended to be a tutorial or even technical, but we do include links to set-up instructions and relevant repos to make it actionable.
Why is IBC special?
The Inter blockchain communication (IBC) protocol is well known as the permissionless interoperability layer of Cosmos (and recently Polkadot). It stands out among many interoperability protocols for too many reasons to list. So I’ll just give a few highlights:
- Battle-tested at scale: IBC processes more than a million messages and more than a hundred million dollars of value every month across a deep, expressive set of application standards (fungible token transfers, non-fungible token transfers, cross-chain queries, cross-chain account control, cross-chain validation/security). Over the last month, IBC has done almost a billion in volume:
- Truly neutral: IBC began as an open source project, and hundreds of developers from numerous teams have contributed to it over the years. Today, a truly decentralized network of 25+ teams are working to improve it, add new capabilities, and expand it to new ecosystems.
- Far + growing reach: IBC currently connects 50+ chains in the Cosmos ecosystem and several in the Polkadot ecosystem (Picasso). Numerous world-class teams are currently working to expand it to Celestia rollups, the OP stack, Ethereum, Solana, and elsewhere.
- Flexible: The core protocol can support any kind of proof (fraud, consensus, multi-sig/committee, validity), already has implementations in multiple languages (Rust, Go) with more coming, and can support any VM.
ibc-go — an implementation of IBC’s core and application protocols in Go — works with the CosmosSDK out-of-the-box and is arguably one of the best reasons to build a Cosmos chain today.
Packet Forward Middleware (PFM)
What it is
PFM enables an IBC token transfer to automatically forward tokens to another chain by triggering another IBC transfer, rather than just depositing them into a local address. (Plus it supports recursion, so it enables n > 2 hops)
Thanks to the Strangelove team for developing PFM.
PFM in a nutshell:
Why it matters
This might not sound that mindblowing, but it’s really crucial for two reasons:
1.Universal 1-hop UX: PFM lets users move tokens between any two chains where an n-length IBC path exists in a single transaction, even when those two chains aren’t connected to each other directly.
For example, suppose a user with Atom on Injective wants to buy an NFT on Stargaze. Injective doesn’t have a direct IBC connection with Stargaze. So without PFM, the user would need to execute two separate transfers: one from Injective to the Hub, then another one from the Hub to Stargaze.
With PFM though, they can move their tokens to Stargaze in just 1 transaction by initiating a transfer to the Hub that uses PFM to hop through the Cosmos Hub (which is connected to both chains) and proceed to Stargaze.
2.Interchain asset routing (i.e. token denom unwinding): (Warning: This one is a little more subtle) Even when two chains are connected directly over IBC — like Osmosis and Stride — PFM is essential for seamlessly moving any asset that has been issued by a third chain — like ATOM— between them.
Without getting into the details too much, the reason is that IBC tags assets based on which chain they’ve been transferred from, and usually one particular version of the asset transferred from one particular chain is much more liquid/useful than all the other versions of the asset. So users don’t just want any ATOM on Osmosis, they want the right version of ATOM. Typically, this is one transferred directly the chain where the asset was originally minted.
That means if a user wants to transfer ATOM from Osmosis to Stride, she must transfer it from Osmosis to the Hub, then from the Hub to Stride. Just like in the previous example, PFM allows her to do this in a single transaction. This is especially useful for widely used assets like liquid staking tokens and stable coins.
**Some folks who don’t work with bridges on a regular basis view this origin tagging as a bug. It’s not! It’s actually a critical security feature because the chain where the token has been transferred to chain is effectively trusting the validator set of the chain from which the token was transferred
The Skip API toolkit makes it easy to help your users always get the correct denom on their destination chain in the fewest transactions possible (More on this later):
Lil’ More Detail
Skip this section if you’re not interested in how PFM works, how to use it, or how to set it up on your chain.
How PFM works
PFM is an IBC middleware. Middlewares sit between core IBC transport / auth functionality and application-specific code, enabling arbitrary new functionality that might be applicable / useful to many applications. Basically, it’s a convenient abstraction for functionality that might be broadly useful to many different applications but doesn’t belong in the core implementation of underlying protocol alongside transport and auth nuts and bolts (e.g. a fee market, packet-forwarding, etc…)
PFM achieves multi-transfer atomicity by delaying acknowledgement / timeout / error packets on intermediate transfers until after the outcome of the next packet in the sequence has been determined. This way, successes/failures waterfall back to the first transfer.
Success case:
Failure case:
How to use PFM
To use PFM, users and developers just need to add a bit of additional JSON-formatted data to the memo field of their IBC transfer packet to describe the channel to which they want to forward their packet :
// other memo fields
"forward": {
"receiver": "chain-c-bech32-address",
"port": "transfer",
"channel": "channel-123"
}
How to enable PFM on a chain
Just follow the instructions in the ibc-apps repo here. It takes just 10-20 minutes and involves the usual steps required for configuring a new CosmosSDK module with a little extra light config required to put the middleware in the right “IBC stack”:
- Import the packages
- Add the module and initialize it
- Add the module’s keeper and initialize it
- Add helper functions
- Add the module’s callbacks to begin and end block
- Configure the IBC application stack
IBC Hooks
What it is
IBC hooks allows an incoming token transfers to call a smart contract on arrival, rather than just depositing them into an address. (It can also be used to call a smart contract as callback upon receiving an ack or a timeout.) If the contract call that the transfer triggers fails/reverts, the transfer reverts as well, sending the tokens back to the chain where they were initially.
ibc hooks in a nutshell:
Why it matters
IBC hooks is a huge unlock because it allows users to interact with smart contracts without needing to bridge to the local chain in a separate step. This is nice because it hides the bridging, which is just a means to an end, from the user. So when a user wants to use an application on a chain where they don’t have funds, she doesn’t need to first need to figure out “how to get to there.” She can just do whatever she’s trying to accomplish by using a frontend that facilitates an end-to-end bridge-then-use flow from another chain, in a single tx.
As a result, different chains can share users more easily, and popular applications on one chain can have direct spillover effects that benefit applications on other chains. In some sense, it brings Cosmos chains closer together and makes them actually feel interoperable.
For example, someone trading on Osmosis can lend on a money market on Neutron or Juno without having to bridge to it explicitly. They can just start earning yield in a single click / transaction, as if the money market were on Osmosis.
On the flip, if the contract call reverts, the transfer operation also reverts. This protects users from situations where their tokens might become stranded in an account on an unfamiliar chain. In our example above, if the money market vault was full, the user’s transfer would revert, so they’d still have their tokens on Osmosis in the account where they started.
Lil’ More Detail
Skip this section if you’re not interested in how IBC-hooks works, how to use it, or how to set it up on your chain.
(IBC hooks is another piece of IBC middleware, so re-read above if you’re wondering what that is).
How to use IBC Hooks
A user / developer can leverage IBC hooks just by adding some additional JSON-formatted metadata to their packet’s memo field that describes what contract to call and what calldata to pass. All this info gets put into the “wasm” field of the memo:
// other memo fields
"wasm": {
"contract": "osmo1contractAddr",
"msg": { // call data
"raw_message_fields": "raw_message_data",
}
}
Besides this, the only thing using IBC hooks requires is that the “receiver” of the transfer (i.e. the address that the tokens are being sent to on the destination chain) matches the contract specified in memo.wasm.contract
(Both PFM and IBC-hooks leverage this pattern of adding additional structured metadata into the memo field. This approach has allowed chains to adopt both protocols without upgrading the underlying transport channels.)
How to enable IBC hooks on a chain
Just follow the instructions in the ibc-apps repo here. It takes just 5-10 minutes and involves the usual steps required for configuring a new CosmosSDK module with a little extra light config required to put the middleware in the right “IBC stack”:
- Import the packages
- Add the module and initialize it
- Add the module’s keeper and initialize it
- Add helper functions
- Add the module’s callbacks to begin and end block
Putting It Together
Hopefully, we’ve convinced you that PFM and IBC Hooks are individually powerful primitives. But really, we love them at Skip and Noble because they truly shine together.
When combined and used creatively, IBC hooks and PFM can create truly magical cross-chain experiences. This is the formula:
Transfer-and-call (i.e. IBC hooks) + n-chain transfer (i.e. PFM) = **Use any smart contract from anywhere, regardless of what token you have or what chain its on —
With the right contracts and routing, the following flows are possible in a single transaction:
-
Send ATOM from Juno to buy axlUSDC on Neutron’s Astroport deployment (after routing through the Hub), then lend it on Umee (after routing through Axelar)
→ 1 transaction, 5 chains
-
Send ATOM from Neutron to Osmosis (after routing through the Hub), buy JUNO, then transfer it to JUNO and stake it to a validator
→ 1 transaction, 4 chains
-
Send USDC from Osmosis to Stargaze (after routing through Noble), buy an NFT, then transfer it to Osmosis
→ 1 transaction, 4 chains
At Skip, we’re working hard to help developers enable all of these flows and more with the Skip API. The Skip and Noble teams are collaborating especially closely on integrations throughout the IBC ecosystem to ensure the Skip API works seamlessly for the most-widely-used, multi-chain assets, like native USDC
Please get in touch if you’re interested in working on these problems and making Cosmos feel more like one chain, while retaining all the benefits of sovereignty.
Takeaways
If you remember anything from this post, have it be this:
- What you can do with IBC today far exceeds what any other interoperability layer can do (this post has barely scratched the surface)
- The ibc-apps repo has lots of great IBC add-ons, which provide massive UX bonuses but aren’t enabled on Cosmos chains by default. More developers should know about it.
- IBC-hooks and PFM are both really easy to set up, and everyone should encourage devs to configure them on every applicable IBC-enabled chain.
- Even though we don’t have the “intents” researchers love to talk about, we can do some incredible things cross-chain, and we can do them today.
- Skip API makes it easy to do these things
About Skip
Skip helps developers provide extraordinary user experiences across all stages of the transaction lifecycle, from transaction construction, through cross-chain relaying + tracking, to block construction.
We build two main products:
- Skip API: A unified REST/RPC service and SDK that helps developers create more seamless cross-chain experiences for their end users with IBC. ****It’s carefully designed so that even developers who are completely new to IBC can use it to build applications and frontends that offer advanced cross chain functionality (e.g. universal IBC denom recommendations, cross-chain DEX aggregation, any-to-any swaps and transfers, multi-chain IBC lifecycle tracking, and much more). IBC.FUN is powered by the Skip API.
- Protocol-owned-builder (POB): A CosmosSDK module that customizes your mempool to provide MEV recapture + protection, advanced fee markets, oracles, and more.
We work closely with the top wallets, protocols, defi aggregators, and chains in the Cosmos ecosystem (Osmosis, Berachain, Stride, Keplr, Leap, Noble, Strangelove, etc…)
Please get in touch if you’re interested in chatting about or using either of these products. Both are available now and free to use.
About Noble
Noble is designed to be the premier asset issuance chain in Cosmos. Appchains need access to natively issued blue chip assets, such as USDC. Noble solves a variety of critical pain points around native issuance, including: security, liquidity, compliance, standardization and neutrality. In the long-term, we envision Noble to exist as an on-ramp for any digital asset to natively access the Interchain ecosystem in a secure, compliant and seamless manner.