Vault.sol¶
Vault 合約持有所有使用者資金,並進行每位使用者的帳本追蹤。它將資產託管與交易邏輯分離。
Vault 存在的意義¶
Vault 實現了免 Gas 的連續交易。若無 Vault,每筆訂單成交都需要一次鏈上代幣轉帳,意味著交易者每筆交易都要支付 Gas。有了 Vault,使用者只需存款一次,餘額便會在內部帳本中追蹤。成交透過 transferLedger 結算 —— 這是一次帳本更新,而非代幣移動 —— 交易者得以持續下單與成交,且無須額外 Gas 成本。
這對專業做市商與金融機構至關重要,他們每天會掛出數百至數千筆訂單。若無 Vault,每筆成交都要支付 Gas,會使 Ethereum 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 | 救回金額超過剩餘量 |