摘要路由问题:
- IBC 会根据资产跨越的 IBC 通道序列为其打标签,因此同一种资产如果经过两条不同路径转移,就会得到两个不同的 denom
- 通常情况下,每种资产在每条链上只有 1 个“正确”的版本(也就是高流动性的版本),而且很多时候一个都没有
- 先把资产发送回其源链
- 找到从源链到目标链的最短路径;如果存在多条不同的最短路径,则使用流动性最高的那一条
- 同时,对少数异常情况保持灵活处理
路由问题
IBC 代币的名称和身份来自其路径
IBC 通过连接两条链的“通道”来传输数据。通道由人类可读的端口名(例如 “transfer”)和通道 ID(例如channel-1)来标识。比如,来看一条连接 Terra2 和 Axelar 的转账通道:

Naming Algorithm
hash 通常是 sha256 哈希函数
继续上面的例子,这个版本的 WETH.axl 在 Terra2 上的 denom 是:
axlWETH on Terra2
不同路径会产生不同的代币
既然你已经理解了 IBC denom 的名称来自其路径,那么也就理解了路由问题的核心:同一种资产如果通过两条不同路径转移到同一个目标链上,就会得到不同的 denom。 继续上面的例子,WETH.axl 如果直接从 Axelar 转到 Terra2,和先经过 Osmosis 再转到 Terra2,得到的 denom 会不同:


两条链之间可能有很多路径,但通常每种资产只有 1 个有用的版本
当前大约有 70 条支持 IBC 的链。这个集合中几乎任意两条链之间至少都存在一条通道。这样一个高密度的通道图,使得几乎任意两条链之间都存在大量不同路径,也就带来了很多“代币绕行”或“路径选错”的机会:用户可能会把资产沿着一条次优的通道路径从一条链发到另一条链,最终得到一个缺乏流动性、几乎无法使用的代币版本。 路径选错几乎总会让用户在目标链上得到一个实际上没什么用且流动性很差的代币版本,因为在给定目标链上,某种资产通常只有 1 个有用的版本(如果有的话)。(JUNO 上有超过 50 个版本的ATOM!)
因此,我们必须非常谨慎,确保用户经过正确的通道序列。下一节会解释我们的代币路由算法。
路由算法
关于路由的一个关键认识:正确路径取决于链和资产本身请注意,某个特定资产 A 从某条链
Chain-1 路由到另一条链 Chain-2 的正确路径,不仅取决于 Chain-1 和 Chain-2 之间有哪些通道,也取决于资产 A 本身是什么。这是因为资产 A 是由它从源头开始的路径定义的。请看下面两种情况:- 如果资产 A 原生于
Chain-1,那么它也许可以直接通过某条通道路由到Chain-2。这样会得到一个较为简单的资产版本,其路径为Chain-1->Chain-2 - 如果资产 A 源自另一条链(例如
Chain-3),那么直接通过某条通道转到Chain-2,极不可能得到Chain-2上正确的资产 A 版本。这样会得到一个更复杂的 denom,其路径为Chain-3->Chain-1->Chain-2;如果Chain-3和Chain-2本身就是直连的,这个结果大概率是错误的。- 更合理的做法通常是,先让资产通过连接
Chain-1和Chain-3的通道返回去,再通过通道发送到Chain-2。这样得到的路径是Chain-1->Chain-3->Chain-2,最终 denom 则由路径Chain-3->Chain-2决定
- 更合理的做法通常是,先让资产通过连接
- 先把给定资产路由回源链(也就是“解开缠绕”)
- 检查对于该资产在目标链上是否存在任何 高优先级 的手动覆盖规则。如果存在,就推荐从源头出发、能够生成这一 高优先级 资产版本的路径
- 如果不存在 高优先级 的手动覆盖规则:
- 如果到目标链至少存在 1 条单跳路径(也就是源链和目标链之间存在 IBC 直连),则推荐流动性最高的直连路径。
- 如果不存在直连路径(或者直连路径上的
client已过期,或者没有任何该资产曾经通过这条直连路径转移过),则不推荐任何资产
- 我们为每条支持的链运行节点,以确保始终能够低延迟访问高质量数据
- 我们每隔几个小时索引一次所有支持链上每条通道及其
client的状态,以确保绝不会推荐那些已经被 relayer 放弃或遗忘的路径。 - 我们每隔几个小时索引一次每条 Cosmos 链上每个通道所转移过的每种代币的流动性,以确保流动性数据保持最新。同时,我们也会密切监控异常的短期流动性变化,以防止攻击
tl;drThe routing problem:
- IBC tags assets based on the sequence of IBC channels they have been transferred over, so the same asset transferred over two different paths will have two different denoms
- Usually, there’s only 1 “correct” (i.e. highly liquid) version of each asset on each chain (and frequently there are none)
- Sending assets to their origin chain
- Find the shortest path from the origin chain to the destination chain, and using the most liquid path when there are multiple distinct shortest paths.
- Plus, staying flexible to unusual exceptions
Routing Problem
IBC Tokens Get Their Names & Identities from Their Paths
IBC transfers data over “channels” that connect two chains. Channels are identified by human-readable port names (e.g. “transfer”) and channel IDs (e.g. channel-1). For example, consider a transfer channel between Terra2 and Axelar:
Naming Algorithm
hash is typically the sha256 hash function
Continuing the example from above, the denom of this version of WETH.axl on Terra2 is:
axlWETH on Terra2
So Different Paths Produce Different Tokens
Now that you understand that IBC denoms get their names from their paths, you understand the crux of the routing problem: The same asset transferred to the same destination over two different paths will have different denominations. Continuing the example from above, WETH.axl transferred directly from Axelar to Terra2 will have a different denom than WETH.axl transferred through Osmosis:

There are many paths between two chains, but usually only 1 useful version of each asset
Right now, there are about 70 IBC-enabled chains. At least one channel exists between almost every pair in this set. This dense graph of channels contains a very large number of different paths between almost any two chains, which creates many opportunities for “token winding” or “mis-pathing”, where a user sends an asset through a suboptimal path of channels from one chain to another and ends up with an illiquid / unusable version of their token. Mis-pathing almost always produces a practically useless + illiquid version of their token on the destination chain because there’s usually only 1 useful version of a given asset on a given destination chain (if that). (There are over 50 versions of ATOM on JUNO!) As a result, we need to be very careful to send the user through the correct sequence of channels. The next section explains our token routing algorithm.Routing Algorithm
Insight about routing: The correct route depends on the chains + the asset in questionNotice that the correct route for a particular asset A on a particular chain Chain-1 to another chain Chain-2 depends not only on the channels that exist between chain-1 and chain-2, but also on what asset-A is.This is because asset A is defined by its path from its origin. Consider the following two cases:
- If asset-A is native to Chain-1, perhaps it can be routed directly over a channel to Chain-2. This would yield a simple asset given by path of Chain-1->Chain-2
- If asset-A originated on another chain (e.g. Chain-3), it’s very unlikely that transferring directly over a channel to Chain-2 would give the correct version of asset A on Chain-2. This would yield a more complex denom given by path of Chain-3->Chain-1->Chain-2, which is probably wrong if Chain-3 and Chain-2 are directly connected.
- Instead, the asset should probably be routed back through the channel that connects Chain-1 to Chain-3 first, then sent over the channel to Chain-2. This yields a path of Chain-1->Chain-3->Chain-2, and a final denom given by the path Chain-3->Chain-2
- Route the given asset back to origin chain (i.e. “unwind” it)
- Check whether any high-priority manual overrides exist for the given asset on the given destination chain. If so, recommend the path from the source that produces this high-priority version of the asset
- If no high priority manual overrides exist:
- If at least 1 single-hop path to the destination chain exists (i.e. if origin chain and destination chain are directly connected over IBC), recommend the most liquid direct path.
- If no direct path exists (or if the client on the direct path is expired, or none of the asset has been transferred over the direct path), do not recommend any asset
- We run nodes for every supported chain to ensure we always have low-latency access to high quality data
- We index client + channel status of every channel + client on all the chains we support every couple of hours to ensure we never recommend a path that relayers have abandoned or forgotten about.
- We index the liquidity of every token transferred over every channel on every Cosmos chain every few hours to ensure our liquidity data is up to date. And we closely monitor anomalous, short-term liquidity movements to prevent attacks