文章介绍了Compound V3中的bulker合约,该合约支持在单个交易中执行多个操作,如抵押、借贷、转账等。文章详细解释了bulker合约的工作原理、安全性设计以及如何处理非标准ERC-20代币。
The bulker contracts in Compound V3 are multicall-like contracts for batching several transactions.
例如,如果我们想在一个交易中提供以太坊、LINK和wBTC作为抵押,并借用USDC,我们可以做到。
我们还可以减少抵押持有量并在一个交易中提取贷款,如下图所示。这当然假设我们保持在抵押因子限制之内。
bulker 的表现与传统的 multicall 不同,它不会接受任意 calldata 列表。相反,它接受两个参数:一个动作列表(共有 6 种选择)以及提供给它们的参数。该函数如下所示。具体来说,我们可以
ACTION_SUPPLY_ASSET
)ACTION_SUPPLY_NATIVE_TOKEN
)ACTION_TRANSFER_ASSET
),请参见我们关于 Compound V3 如何像重基 ERC 20 代币运行的文章 以了解其工作原理ACTION_WITHDRAW_ASSET
)ACTION_WITHDRAW_NATIVE_TOKEN
)Invoke 会遍历这些操作并使用提供的参数调用 Comet(或奖励合约)。
虽然将此代码放入主合约中可能会更节省 gas,但在循环中使用 msg.value,尤其是在调用 delegatecall 时,并不安全。请参阅本文末尾的练习问题。
Compound 小心确保 msg.value 被扣减而不是再次使用,这可能导致双重支付——请参见黄色框。
可以说,这本可以通过使用 1 字节指示符而不是 32 字节 ASCII 字符串指示符来进行 gas 优化。
bulker 不会持有用户的代币。相反,用户给 bulker 授权,bulker 代表用户将资产提供给 Compound。Compound 并不假设 msg.sender
是存款人;这样做通常不是一个好的设计模式,因为这破坏了组合性——它阻止其他合约代表用户采取行动。
如果用户意外地将代币转移到 bulker,管理员可以移除代币。注意我们有单独的功能用于移除被卡住的 ETH 和被卡住的 ERC 20 代币。
偏离 ERC 20 代币规范的最常见情况之一是未返回布尔值。一些 ERC 20 代币在失败情况下不会返回布尔值,而是会 revert。
为处理在处理 ERC 20 资产时的这两种情况,Compound 实施了以下代码:
IERC20NonStandard 没有返回值——如果处理的是非标准 ERC 20 代币,它将 revert。为了处理这实际上是标准 ERC 20 代币的可能性,返回数据大小为 32 字节的情况将表示该代币确实返回了一个值。如果返回的值是 1,则表示成功;否则失败。不同的场景在下表中捕获。
基本上,我们在以下情况下成功:(代币不 revert 并且无返回值)或(代币不 revert 并且返回 true)。我们在以下情况下失败:(代币 revert)或(代币不 revert 并且返回 false)。
IERC20Nonstandard 接口 只是定义了一个不返回任何布尔值的 ERC20 代币。
在循环中使用 msg.value
时可能会发生不良情况。请查看这两个练习问题:
请查看我们的 web3 bootcamp 以了解更多信息。
最初发布于 2024 年 1 月 9 日
- 原文链接: rareskills.io/post/compo...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~
如果觉得我的文章对您有用,请随意打赏。你的支持将鼓励我继续创作!