Juicebox 协议:如何准备已部署项目的审计

  • zealynx
  • 发布于 2023-05-20 12:59
  • 阅读 47

这篇文章是为 Juicebox Buyback Delegate 审计准备的总结。它详细介绍了 Juicebox 协议的概览、核心与表面合约架构,包括 JBTokenStore, JBSplitsStore, JBPrices 等关键组件的功能。随后,文章深入探讨了回购合约、数据源合约和委托合约的概念,并具体分析了 JBXBuybackDelegate.sol 的主要外部函数及其实现逻辑。

在公开的漏洞赏金竞赛中,项目通常不仅已经部署,而且已经过一次或多次审计。

因此,你必须习惯于分析项目并根据其网站和文档创建摘要。

好消息是,在此期间,你正在阅读相关内容,研究其现有代码库,并将所有信息整合起来使其有意义。

以下是我为 Juicebox Buyback Delegate 审计准备摘要的方式。


概述

Juicebox 协议是一个用于在以太坊上公开资助和运营项目的框架。它用途广泛,允许你构建从 NFT 项目到精品加密法律事务所的任何事物——这意味着几乎任何你想实现的创意。

  • 你可以启动一个具有治理功能的 DAO
  • 具有强大金库管理和赎回功能的一站式众筹
  • 如上所述,你可以构建并启动你的 NFT 项目

Juicebox NFT project

Juicebox governance

Juicebox governance minimal

Juicebox 是一个治理极简协议。只有少数可以调整的杠杆,所有这些都不会在未经用户同意的情况下强加更改。

当然,治理智能合约负责调整这些杠杆。

他们的治理代币是 JBX 代币。


架构

该协议由 7 个核心合约和 3 个表面合约组成。

核心合约

以下是一些最相关的核心合约:

JBTokenStore

管理所有项目的代币铸造和销毁。

mintFor 的逐步解释:

1function mintFor(
2  address _holder,
3  uint256 _projectId,
4  uint256 _amount,
5  bool _preferClaimedTokens
6) external override onlyController(_projectId) { ... }

burnFrom 的逐步解释:

1function burnFrom(
2  address _holder,
3  uint256 _projectId,
4  uint256 _amount,
5  bool _preferClaimedTokens
6) external override onlyController(_projectId) { ... }

issueFor 的逐步解释:

1function issueFor(
2  uint256 _projectId,
3  string calldata _name,
4  string calldata _symbol
5)
6  external
7  override
8  requirePermission(projects.ownerOf(_projectId), _projectId, JBOperations.ISSUE)
9  returns (IJBToken token)
10{ ... }

JBSplitsStore

存储关于任意分配应如何拆分的信息。这些信息以 JBSplit 数据结构表示。

  • 一个项目可以为任意数量的组存储拆分,例如用于支付分配或预留代币分配。
  • 一个拆分可以指定一个地址、一个 Juicebox 项目、一个遵循 IJBSplitAllocator 接口的合约,或者调用交易以分配支付或预留代币的地址作为其接收者。
  • 默认情况下,拆分可以在任何资金周期配置的任何时候更改。项目所有者还可以独立地将拆分锁定到资金周期配置中,并持续可定制的时间。

set 的逐步解释:

1function set(
2  uint256 _projectId,
3  uint256 _domain,
4  JBGroupedSplits[] calldata _groupedSplits
5)
6  external
7  override
8  requirePermissionAllowingOverride(
9      projects.ownerOf(_projectId),
10      _projectId,
11      JBOperations.SET_SPLITS,
12      address(directory.controllerOf(_projectId)) == msg.sender
13  ) { ... }

这是 JBSplit 结构体:

1/**
2  @member preferClaimed 一个标志,仅在指定了 projectId 且项目附加了代币合约时生效。如果是,此标志表示向项目付款产生的代币应该作为**已申领**的代币交付到受益人的钱包,还是作为**未申领**的代币以节省 gas。
3  @member preferAddToBalance 一个标志,表示向项目分配时是否应优先触发其 addToBalance 函数而不是其 pay 函数。
4  @member percent 此拆分在整个组中所占的百分比。此数字以 `JBConstants.SPLITS_TOTAL_PERCENT` 为基数。
5  @member projectId 项目 ID。如果未设置分配器但设置了 projectId,资金将发送到指定 ID 项目的协议金库。
6  @member beneficiary 一个地址。受益人的角色取决于是否指定了 projectId,以及是否指定了分配器。
7  @member lockedUntil 指定拆分是否应保持不可更改,直到指定时间,除非延长锁定周期。
8  @member allocator 如果指定了分配器,资金将与此拆分的所有属性一起发送到分配器合约。
9*/
10struct JBSplit {
11  bool preferClaimed;
12  bool preferAddToBalance;
13  uint256 percent;
14  uint256 projectId;
15  address payable beneficiary;
16  uint256 lockedUntil;
17  IJBSplitAllocator allocator;
18}

JBPrices

管理和标准化各种货币的价格源。

协议使用此功能允许项目以任意数量的货币进行核算,但无论核算面额如何,都以 ETH 或其他资产管理所有资金。

feedFor 属性:

1// 可用的价格源。
2// 该价格源返回可转换为 1 个 `_base` 单位的 `_currency` 单位数量。
3

4mapping(uint256 => mapping(uint256 => IJBPriceFeed)) public override feedFor;

addFeedFor 的逐步解释:

1function addFeedFor(
2  uint256 _currency,
3  uint256 _base,
4  IJBPriceFeed _feed
5) external override onlyOwner { ... }

表面合约

有三个主要的表面合约管理项目如何管理资金并定义所有核心合约应如何协同使用。

  • JBController3_1 — 协调资金周期和项目代币,实现受限的控制、核算和代币管理。

  • JBPayoutRedemptionPaymentTerminal3_1 — 管理所有资金流入和流出。

  • JBSingleTokenPaymentTerminalStore3_1 — 代表仅管理一种代币类型的支付终端管理核算数据。

    • *

Juice Buyback Delegate

Juice 回购提供了一个数据源和 Delegate,它在贡献者在终端上调用 pay 时,最大化其收到的项目代币数量。

什么是 Buyback 合约?

  • 它允许零售商以约定价格退回未售出的库存,数量不超过指定金额。
  • 它增加了零售商的最佳订购数量,从而提高了产品可用性,并为零售商和供应商带来了更高的利润。

什么是 Data source 合约?

  • Data source 合约是一种为金库提供扩展的方式,它要么覆盖要么增强默认的支付赎回支付功能。
  • Data source 合约可用于为 pay(...) 交易和/或 redeemTokensOf(...) 交易提供自定义数据。
  • Data source 负责指定在 pay(...)redeemTokensOf(...) 交易的核心功能成功执行后应触发的任何 Delegate Hook。

什么是 Delegate 合约?

  • Delegate 合约是一种为金库提供扩展的方式,它增强了默认的支付赎回支付行为。

  • 支付 Delegate 包含一个自定义的 didPay(...) Hook,该Hook将在所有默认协议支付逻辑在终端合约中成功执行后执行。

  • 赎回 Delegate 包含一个自定义的 didRedeem(...) Hook,该Hook将在所有默认协议赎回逻辑在终端合约中成功执行后执行。

    • *

JBXBuybackDelegate.sol

Datasource 和 Delegate 允许支付受益人在使用项目权重铸造和在给定 Uniswap V3 池中兑换之间获得最高数量的项目代币。

Buyback delegate flow

合约的主要外部函数:

payParams()

处理数据源的实现。返回要使用的权重、传入的原始备忘录以及发送给 Delegate 而非添加到本地余额的金额。

1function payParams(JBPayParamsData calldata _data) external override
2  returns (
3    uint256 weight,
4    string memory memo,
5    JBPayDelegateAllocation[] memory delegateAllocations
6  )

didPay()

委托给受益人进行兑换或铸造给受益人。

仅当兑换报价高于铸造时收到的最低金额时才调用此 Delegate。

1function didPay(JBDidPayData calldata _data) external payable override

uniswapV3SwapCallback()

代币转账应发生的地方。

1function uniswapV3SwapCallback(
2  int256 amount0Delta,
3  int256 amount1Delta,
4  bytes calldata data
5) external override

希望你能在审计期间利用这一点,甚至在审计之后进行练习。

此外,将其作为如何准备审计的示例。


联系我们

正在准备智能合约审计或对已部署的协议运行漏洞赏金?彻底了解架构是发现其他人遗漏之处的第一步。

在 Zealynx,我们专注于 DeFi 协议的深度安全审计——从 Juicebox 这样的金库管理系统到复杂的 DEX 集成。

需要审计或对你已部署的合约进行二次审查吗?获取报价直接联系讨论你的项目。

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

0 条评论

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