Vault.sol¶
Vault 合约保管所有用户资金,具有按用户的账本跟踪。它将资产托管与交易逻辑分离。
Vault 存在的意义¶
Vault 实现了无 Gas 的连续交易。没有它,每次订单成交都需要一次链上代币转账,这意味着交易者每笔交易都要支付 Gas。有了 Vault,用户只需存款一次,余额便在内部账本中跟踪。成交通过 transferLedger 结算 —— 这是一次账本更新,而非代币移动 —— 因此交易者可以持续下单和成交,无需额外 Gas 成本。
这对专业做市商和金融机构至关重要,他们每天会下数百乃至数千笔订单。如果没有 Vault,每次成交都要付 Gas,会让以太坊 L1 上的主动做市经济上不可行。Vault 允许他们一次性存入抵押品,随后以链下撮合引擎的速度持续交易,仅在存款和提款时支付 Gas。
主网: 0xC7d4Fd2638e6630C8C61329878676b88A8A24D43 源代码: src/Vault.sol
函数¶
deposit¶
从用户钱包拉取代币到 Vault。
| 参数 | 类型 | 说明 |
|---|---|---|
user | address | 受益账户 |
token | address | ERC-20 代币地址 |
amount | uint256 | 存入金额 |
要求:
- 调用者必须拥有
TRADER_ROLE - 用户不能在黑名单中
- 金额必须 > 0
- 用户必须已授权 Vault 花费该代币
事件:
creditLedger¶
记入用户的 Vault 余额。调用者必须在同一交易中已将代币转入 Vault。
| 参数 | 类型 | 说明 |
|---|---|---|
user | address | 受益账户 |
token | address | ERC-20 代币地址 |
expectedAmount | uint256 | 记入金额 |
withdraw¶
扣减用户的 Vault 余额并将代币转给接收方。
| 参数 | 类型 | 说明 |
|---|---|---|
user | address | 被扣减的账户 |
token | address | ERC-20 代币地址 |
amount | uint256 | 提取金额 |
to | address | 代币接收方 |
要求:
to不能为零地址- 金额必须 > 0
- 用户余额必须充足
事件:
transferLedger¶
两个用户之间的内部账本转账。不发生 ERC-20 代币移动。
| 参数 | 类型 | 说明 |
|---|---|---|
fromUser | address | 来源账户 |
toUser | address | 目标账户 |
token | address | ERC-20 代币地址 |
amount | uint256 | 转账金额 |
此函数在订单结算期间内部使用。Vault 的总 TVL 保持不变。
事件:
event Withdrawn(address indexed token, address indexed user, uint256 amount); // fromUser
event Deposited(address indexed token, address indexed user, uint256 amount); // toUser
两个事件都会发出,目的是让标准的子图索引器能与账本变化保持同步,即使实际上并没有 ERC-20 转账发生。
balanceOf¶
查询用户在特定代币上的 Vault 余额。
查询 Vault 持有的总物理 ERC-20 余额:
setBlacklisted¶
将用户账户加入黑名单或从黑名单中移除。
被列入黑名单的用户不能存款或接收记入,但仍然可以提取现有余额。
事件:
isBlacklisted¶
检查用户是否在黑名单中。
rescueToken¶
救回意外直接发送到 Vault(而非通过存款)的代币。
只能救回多余的代币(物理余额减去已跟踪余额)。用户已跟踪的资金不能被救回。
错误¶
| 错误 | 原因 |
|---|---|
BlacklistedUser | 用户在黑名单中(存款/记入被阻止) |
ZeroAmount | 金额为 0 |
ZeroAddress | 接收方或用户为零地址 |
InsufficientBalance | 用户余额不足 |
CannotRescueTrackedFunds | 尝试救回已跟踪的用户资金 |
InsufficientSurplus | 救回金额超过多余部分 |