使用 safe-utils 和 tenderly-utils 自动化你的安全运营

  • Recon
  • 发布于 9小时前
  • 阅读 43

本文介绍了如何使用 safe-utils 和 tenderly-utils 这两个 Foundry 模块来简化协议的治理流程,尤其是在涉及 Safe 多签账户的场景下。

治理提案的正确方式

探讨 safe-utilstenderly-utils 如何帮助简化多重签名交易提案和模拟。如果你的 DAO 或协议不断地将更新推送到生产环境,本文将对你有所帮助。

在构建可升级或可配置的协议时,一种常见的设置是将治理权委托给 Safe 智能账户,可能位于 时间锁或 Governor 合约 之后。

一方面,让多个签名者审查配置或协议更新可以减少风险,因为这样可以让更多人检查提议的更改。另一方面,大多数协议仍然依赖 Safe UI 来提出这些交易,这对于复杂的更新来说可能很麻烦,并且很难让受信任的各方审查。

为了缓解这些缺点,我们推出了两个 Foundry 模块:safe-utilstenderly-utils,它们可以用最少的设置来帮助简化此过程。这些库可以单独使用或一起使用,在本文中,我们提出了一个框架来改进协议的治理操作。

使用 safe-utils 和 tenderly-utils 自动化你的安全操作

safe-utils

safe-utils 库支持从 Foundry 脚本向 Safe API 提出多重签名交易。

安装

forge install Recon-Fuzz/safe-utils

用法

import {Safe} from "safe-utils/Safe.sol";
using Safe for *;

Safe.Client safe;

function setUp() public {
  safe.initialize(vm.envAddress("SAFE_ADDRESS"));
}

提出一项交易

safe.proposeTransaction(
  target,
  abi.encodeCall(Contract.functionName, (args)),
  signer
);

该提案经过签名并发布到 Safe API 后端,以便稍后由其他 Safe 所有者批准。通过将提案实现为 Foundry 脚本,安全研究人员可以帮助审查、发现潜在问题并减轻风险。

tenderly-utils

tenderly-utils 库提供了一个与 Tenderly API 的接口,用于自动化模拟和虚拟测试网创建。 它可以与 safe-utils 模块结合使用,以便提案可以立即应用于 Fork 网络。 这非常有用,前端和后端团队可以在治理更新生效之前立即对其进行测试。

安装

forge install Recon-Fuzz/tenderly-utils

用法

import {Tenderly} from "tenderly-utils/Tenderly.sol";
using Tenderly for *;

Tenderly.Client tenderly;

function setUp() public {
  tenderly.initialize(
    vm.envString("TENDERLY_ACCOUNT_NAME"),
    vm.envString("TENDERLY_PROJECT_NAME"),
    vm.envString("TENDERLY_ACCESS_KEY")
  );
}

在 Fork 上模拟交易

Tenderly.VirtualTestnet memory vnet =
  tenderly.createVirtualTestnet("vnet", block.chainid);

Tenderly.Transaction memory transaction = tenderly.sendTransaction(
  vnet.id, from, weth, abi.encodeCall(IWETH.withdraw.selector, (amount))
);

虚拟测试网是一个你可以与你的团队共享的链 Fork,它反映了模拟状态。 对于多重签名提案,这非常有用,因为你还可以使用像 setStorageAt 这样的作弊码将 Safe 阈值更改为 1,并立即让治理提案通过。 这正是你点击 “Simulate transaction” 时通过 Safe UI 发生的事情。

端到端的设置

Size Credit(一个具有统一流动性的固定利率借贷市场)中,这些库的使用方式如下:

部署

过去,新的货币市场是通过管理前端部署的。 这很难维护,因为它需要频繁的安全更新以最大程度地减少用户输入错误,而这些错误非常频繁。 现在,部署使用 Foundry 脚本,该脚本更易于审查和扩展。 可以通过获取市场注册表并仅更新一些参数(例如抵押品/债务代币和价格 Feed)来克隆现有配置,从而降低人为错误的风险。

ProposeSafeTxDeployPTMarkets.s.sol

在底层,proposeTransaction 函数对操作进行签名,并使用 Safe execTransaction 方法参数向 Safe API Kit 后端提交 HTTP 请求。

更新

协议更新通常涉及将批量交易提交到多个地址。 以前,这是通过 Safe 前端的“Batch Transaction”工具完成的。 这非常容易出错且耗时,因为它有很多手动步骤:复制合约地址,复制 ABI,复制更新参数,确保它们已正确格式化,然后对所有必要的更改重复执行此操作。 使用 safe-utils 可以通过编程方式构造此操作,从而防止人为错误,例如忘记更新一个市场、将更新提交到无效地址以及其他错误,所有这些错误已经在生产中发生过。

ProposeSafeTxUpdateConfig.s.sol

在实现方面,proposeTransactions (复数,因为它可用于传递多个子调用)辅助函数将使用与底层的 Safe SDK 相同的 MultiSendCallOnly 批量聚合器合约。 使用 safe-utils 库而不是手动调用 MultiSendCallOnly 的好处是,它提供了一个更简单的接口,因为开发人员无需手动构造 multiSend 参数,因为它具有非常特定的编码。 一个重要的底层细节是,必须通过 DelegateCall 进行 execTransaction operation 参数,以确保交易上下文(包括 msg.sender)在交易链中的所有子调用中都保持为 Safe 帐户。

模拟

在部署新的货币市场之前,协议需要进行多项分析以确定风险参数,例如抵押率和清算奖励。 使用不同的配置执行实际清算可以帮助更全面地了解价格对 DEX 的影响以及流动性如何受到价格变化的影响。

tenderly-utils 的帮助下创建的 Tenderly 虚拟测试网可以成为模拟借款、价格下跌和清算事件的有用工具。 然后,清算引擎可以使用闪电贷来偿还借款并评估此 Fork 网络上的总体输出,然后根据调查结果调整治理参数。

SimulateBorrowerLiquidatable.s.sol

荣誉奖:solidity-http

正如你可以想象的那样,这些 API 触发器在底层是经过美化的 HTTP 调用,使用 Foundry 的 vm.serialize* 正确编码,并使用 vm.parseJson 解码。 为了实现这些请求,开发了一个轻量级的 solidity-http 客户端库,其灵感来自 axios,可以通过 ffi 轻松访问 curl

结论

通过结合 safe-utilstenderly-utils,我们提出了一个脚本化完整 Safe 交易生命周期的框架:

  • 编码批量或单笔交易

  • 向 Safe API 提出交易

  • 通过 Tenderly Fork 模拟执行并覆盖阈值

  • 与你的团队共享虚拟测试网

此设置已为 DAO 工作流程、协议治理和多重签名操作做好准备。 如果你有兴趣让受信任的合作伙伴审查你的治理操作,可以联系 Recon


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

0 条评论

请先 登录 后评论
Recon
Recon
江湖只有他的大名,没有他的介绍。