使用 LayerZero 开发时需要检查的 6 件事

  • Ackee
  • 发布于 2022-09-13 21:15
  • 阅读 43

本文为使用 LayerZero 构建跨链 dApp 的开发者提供了一个快速检查清单,以避免常见的安全问题。清单内容包括:设置正确的 Endpoint 地址、仔细验证消息来源、确保来自不可信地址的消息不被执行、在不同的链上使用不同的合约、谨慎使用 LayerZero 示例合约,以及考虑使用自定义 Relayer 以实现更高的安全性。

使用 LayerZero 进行构建的开发者有时难以理解该协议,这可能会导致严重的安全问题。我们提供了一份快速检查清单,以帮助避免最常见的错误。

LayerZero

LayerZero一种为跨链消息传递而设计的协议。它能够实现各种跨链应用,无论是跨链去中心化交易所还是多链收益聚合器。目前,LayerZero 支持 Ethereum 和 EVM 兼容链,如 Binance Smart Chain、Avalanche、Polygon、Moonbeam、Arbitrum、Optimism、Fantom、Swimmer、DFK 和 Harmony。

LayerZero 能够实现各种跨链应用,无论是跨链去中心化交易所还是多链收益聚合器。目前,LayerZero 支持 Ethereum 和 EVM 兼容链,如 Binance Smart Chain、Avalanche、Polygon、Moonbeam、Arbitrum、Optimism、Fantom、Swimmer、DFK 和 Harmony。

在本文中,你不会学习 LayerZero 的工作原理 - 为此,你可以阅读白皮书并学习文档。我们从审计师的角度介绍 6 个有意义的检查点。

1. 设置正确的 Endpoint 地址

LayerZero 中的消息由 LayerZero Endpoint 智能合约发送和接收;任何想要通过该协议与其他区块链通信的区块链都必须部署此特定合约。

你的 LayerZero 应用程序需要知道其各自区块链上 Endpoint 合约的地址,以便跨链发送和接收消息。

当然,这个合约部署的地址在每个支持的链上都不同。所以不要在这里犯错,记住在将合约部署到不同的链上或从测试网部署到主网时,相应地更改 Endpoint 地址。主网的地址可以在这里找到,测试网的地址可以在这里找到。

2. 仔细验证消息来源

要接收跨链消息,你的合约必须实现 lzReceive 函数;每次 Endpoint 为你的合约提供新消息时,都会调用此函数。

现在有两层消息验证。任何人都可以调用此函数:你需要检查此交易的发送者是否为 Endpoint 合约。这是首先要做的,也是显而易见的事情。

但是,在源链上,任何人都可以将跨链消息发送到你链上的地址 - Endpoint 会将此消息传递到你的合约。因此,应该构建第二层身份验证来验证源链上的消息发送者

例如,假设你正在构建 Ethereum 和 BSC 之间的跨链 Token。在这种情况下,Ethereum 智能合约上的 lzReceive 由 Ethereum Endpoint 调用,并且消息应该仅来自 BSC 上的 BSC Token 智能合约。

require(_msgSender() == address(lzEndpoint)); // on dest chain

require(_srcAddress == bscTokenAddress); // on src chain

在构建跨链 dApp 时,为每个链设置一个受信任的地址,并保留所有者更改它们的能力是有意义的。

3. 不得执行来自不受信任地址的消息

确保在任何情况下都不能执行来自不受信任的远程地址(在源链上)的消息。举个例子:

假设你已经在构建 LayerZero 跨链 dApp。很可能,你已经构建了一种用于存储和重新运行失败消息的逻辑(即,已接收和验证的消息,但它们的执行以某种方式失败;它们可能是 out-of-gas 异常等)。可能会发生任何人都可以重新运行存储的失败消息而无需任何检查。合约的所有者(你)也能够更改受信任的远程地址。

现在想象一下,你的合约收到来自受信任地址的消息,但执行失败;它被存储了。但是,源链上的受信任合约发生了一些不好的事情,因此你更改了受信任的地址。我们现在已经到了这样一种情况:任何人都可以执行来自不受信任的远程地址的失败消息。

我们建议在每次执行消息之前进行适当的检查

4. 不同链上的不同合约

你可能需要在不同的链上使用不同的合约。一旦你稍微思考一下,这就会很明显。

例如,如果你正在开发一种可通过 LayerZero 协议转移的跨链 wrapped Ether,则除了发送和接收函数外,Ethereum 链上的合约还必须具有存款和取款函数(在 ETH 和你的 wrapped ETH 跨链 Token 之间)。

同时,其他链上的合约应该有所不同;它们应该具有跨链互操作性所需的发送和接收函数,但它们不能具有存款和取款函数。否则,例如,用户将能够在 BSC 上存入 10 个 BNB,将 wrapped 资产发送到 Ethereum,并在那里提取 10 个 ETH。

5. LayerZero 示例合约

LayerZero 提供了许多跨链合约的示例。特别是,有各种跨链 Token 以及 LayerZero 应用程序的基本模板:LzAppNonblockingLzApp。LayerZero 文档甚至鼓励开发人员使用这些模板在其合约中实现 LayerZero 消息传递。

我们很自豪地说,我们审计了这些示例合约,因此我们认为它们是安全的。我们鼓励你花时间审查它们,看看它们是否对你有任何用处。但是,请明智地使用它们,并在在其之上构建时保持谨慎。

6. 自定义 Relayer

为了正常运行并跨链传递消息,LayerZero 协议依赖于两个参与者:Oracle 和 Relayer。唯一的要求是这些实体是独立的,因此它们不能相互勾结。

默认情况下,所有用户应用程序都将使用 LayerZero 提供的 Relayer。但是,如果你想实现毫不妥协的安全性,你可以开发自己的 Relayer。这样,你可以确保两个必要的参与者始终是独立的。

就这样 – 使用 LayerZero 开发 dApp 的 6 个检查点。我们希望你觉得这篇文章有用,并且可以帮助你构建自己的应用程序。

  • 原文链接: ackee.xyz/blog/6-things-...
  • 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
点赞 0
收藏 0
分享
本文参与登链社区写作激励计划 ,好文好收益,欢迎正在阅读的你也加入。

0 条评论

请先 登录 后评论
Ackee
Ackee
Cybersecurity experts | We audit Ethereum and Solana | Creators of @WakeFramework , Solidity (Wake) & @TridentSolana | Educational partner of Solana Foundation