theirrationalone/escrow-2026-04
GitHub: theirrationalone/escrow-2026-04
一个基于 Solidity 的链上托管合约协议,为智能合约审计员与项目方提供可信中立的资金托管与可选争议仲裁服务。
Stars: 0 | Forks: 0
# CodeHawks 托管合约
## 竞赛详情
- 总奖金池:$40,000
- HM 奖励:$37,000
- LQAG 奖励:$3,000
- 开始时间:2023 年 7 月 24 日
- 结束时间:2023 年 8 月 5 日
- nSLOC:~182
- 复杂度评分:~106
### 项目概述
### 关于
本项目旨在为智能合约审计员(卖家)和寻找审计服务的智能合约协议(买家)提供一个连接渠道,使用一个可信中立的选项,并支持可选的仲裁。
**参与者**
* Buyer (买家):服务的购买者,在此场景中为购买审计服务的项目方。
* Seller (卖家):服务的提供者,在此场景中为愿意审计项目的审计员。
* Arbiter (仲裁员):中立的、受信任的参与者,可以解决买家和卖家之间的争议。
**设计考量**
* 仲裁员只有在发生争议时才能获得 `arbiterFee` 金额的补偿。
* 一旦争议被发起,就无法取消。
* 不应使用 ERC777 代币作为 `Escrow` 合约的代币,因为它可能允许恶意买家对 `Escrow::resolveDispute` 进行拒绝服务攻击(DOS)。
* 如果智能合约调用 `EscrowFactory::newEscrow`,考虑到该合约的调用者可以控制 salt,存在被抢跑的可能性。
### 工作流
**创建 `Escrow`**
1. 买家批准由 `EscrowFactory` 处理的支付合约。
2. 买家调用 `EscrowFactory::newEscrow`,输入以下参数:
1. 价格。
2. 支付代币。
3. 卖家(审计员或负责审计的人员)。
4. 仲裁员。
5. 仲裁费:在争议发生时需支付的费用将被初始化。
6. Salt:用于 `create2` 部署 `Escrow`。
**预期的成功工作流**
1. 买家通过 `EscrowFactory::newEscrow` 创建一个 `Escrow` 合约,并存入资金。
2. 卖家向买家发送报告(链下)。
3. 买家通过调用 `Escrow::confirmReceipt` 在链上确认该报告。这会将资金发送给卖家。
**预期的争议工作流**
1. 买家通过 `EscrowFactory::newEscrow` 创建一个 `Escrow` 合约,并存入资金。
2. 出于任何原因,买家或卖家可以通过 `Escrow::initiateDispute` 发起争议。
3. 仲裁员在链下与双方进行协商。随后,仲裁员调用 `Escrow::resolveDispute`,为相应的一方退款,并清空 `Escrow` 合约中的资金。
## 致谢
- 代码库的灵感来自 [Ross Campbell](https://www.linkedin.com/in/ross-campbell-058153aa/)
[//]: # (contest-details-close)
## 审查范围
`src` 中的所有合约均在审查范围内。
*关于 `script` 文件夹的说明*:
`script` 中的合约是您可以假定将被用于部署和交互的脚本。如果它们存在会影响系统整体安全性的问题,则属于审查范围。但是,如果它们的安全问题仅影响脚本本身而不影响托管协议的整体部署,则不在审查范围内。
## 已知问题
* **非零地址(例如 0xdead)可能会导致争议无法解决** - 在 `buyer` 部署新的 `Escrow` 之前,`buyer` 和 `seller` 应就 `Escrow` 的条款达成一致。如果 `buyer` 意外或恶意部署了带有错误 `arbiter` 信息的 `Escrow`,那么 `seller` 可以拒绝提供服务。鉴于 `buyer` 是部署新 `Escrow` 并锁定资金的参与者,正确部署符合其最大利益。
* **过高的仲裁费会导致 `seller` 获得极少甚至没有报酬** - 在这种情况下,`seller` 可以决定不执行审计。如果发生这种情况,`buyer` 收回任何资金的唯一途径就是启动争议程序,而在该程序中,`buyer` 会将其存入的大部分资金损失给 `arbiter`。因此,`buyer` 会被抑制,不会以这种方式部署新的 `Escrow`。
* **带有回调机制的代币允许恶意卖家对争议解决进行拒绝服务攻击(DOS)** - 每种受支持的代币都将经过严格审查以确认其支持资格。应当 discourged(不建议)使用 ERC777。
* **`buyer` 从不调用 `confirmReceipt`** - `Escrow` 的条款在部署之前已由 `buyer` 和 `seller` 达成一致。`seller` 有责任在决定向 `buyer` 提供服务之前,对 `buyer` 及其链下身份/信誉进行尽职调查。
* **创建 `Escrow` 时输入的 `salt` 可能被抢跑**
* **`arbiter` 是一个受信任的角色**
* **用户错误,例如 `buyer` 过早调用 `confirmReceipt`**
* **非 `tokenAddress` 资金被锁定**
# 入门指南
## 环境要求
- [git](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
- 如果你运行 `git --version` 并看到类似 `git version x.x.x` 的响应,就说明你安装正确了
- [foundry](https://getfoundry.sh/)
- 如果你运行 `forge --version` 并看到类似 `forge 0.2.0 (816e00b 2023-03-16T00:05:26.396218Z)` 的响应,就说明你安装正确了
## 快速启动
```
git clone https://github.com/Cyfrin/2023-07-escrow
cd escrow
forge build
```
# 使用方法
## 测试
```
forge test
```
### 测试覆盖率
```
forge coverage
```
以及基于覆盖率的测试:
```
forge coverage --report debug
```
## 启动本地节点
```
make anvil
```
## 部署
这将默认部署到你的本地节点。你需要让它在另一个终端中运行,以便进行部署。
```
make deploy
```
## 部署 - 其他网络
[见下文](#deployment-to-a-testnet-or-mainnet)
# 部署到测试网或主网
1. 设置环境变量
你需要将 `SEPOLIA_RPC_URL` 和 `PRIVATE_KEY` 设置为环境变量。你可以将它们添加到 `.env` 文件中,类似于你在 `.env.example` 中看到的内容。
- `PRIVATE_KEY`:你账户的私钥(比如来自 [metamask](https://metamask.io/))。**注意:**用于开发时,请使用没有关联任何真实资金的密钥。
- 你可以[在这里了解如何导出它](https://metamask.zendesk.com/hc/en-us/articles/360015289632-How-to-Export-an-Account-Private-Key)。
- `SEPOLIA_RPC_URL`:这是你正在使用的 goerli 测试网节点的 URL。你可以从 [Alchemy](https://alchemy.com/?a=673c802981) 免费获取并设置一个。
可选地,如果你想在 [Etherscan](https://etherscan.io/) 上验证你的合约,请添加你的 `ETHERSCAN_API_KEY`。
1. 获取测试网 ETH
前往 [faucets.chain.link](https://faucets.chain.link/) 获取一些测试网 ETH。你应该会看到 ETH 显示在你的 metamask 中。
2. 部署
```
make deploy ARGS="--network sepolia"
```
## 估算 Gas
你可以通过运行以下命令来估算各项操作所消耗的 Gas:
```
forge snapshot
```
然后你会看到一个名为 `.gas-snapshot` 的输出文件。
# 格式化
要运行代码格式化:
```
forge fmt
```
标签:CodeHawks, Create2, Cyfrin, DeFi, DOS攻击防护, ERC20, Escrow合约, Solidity, Web3, 仲裁机制, 区块链安全, 去中心化应用, 审计平台, 工厂合约, 智能合约, 智能合约审计, 防抢跑