# 跨链桥

## 1. 项目概述

该桥允许在两链之间进行双向稳定币转移 **BSC** 和 **AIC**:

* `BSC -> AIC`： 锁定 `USDT` 在 BSC 上并接收 `USDI` 在 AIC 上
* `AIC -> BSC`： 锁定 `USDI` 在 AIC 上并接收 `USDT` 在 BSC 上

该协议遵循 **源链存款 + 目标链认领** 模型。\
`认领` 执行由验证者多签名授权，使用 **EIP-712** 类型化数据。

***

### 2. 网络与合约地址

### 2.1 链信息

| 网络  |   链 ID | RPC                                | 区块浏览器                      |
| --- | -----: | ---------------------------------- | -------------------------- |
| BSC |   `56` | `https://bsc-dataseed.binance.org` | `https://bscscan.com`      |
| AIC | `3018` | `https://rpc.aicchain.io`          | `https://scan.aicchain.io` |

### 2.2 代币地址

| 资产   | 网络  | 合约地址                                         | 小数位 |
| ---- | --- | -------------------------------------------- | --: |
| USDT | BSC | `0x55d398326f99059fF775485246999027B3197955` |  18 |
| USDI | AIC | `0xD359Ebfa22d6caFe8Ff49b9e45859F688243CdAC` |  18 |

### 2.3 桥合约地址

| 网络    | 桥地址                                          |
| ----- | -------------------------------------------- |
| BSC 桥 | `0x9a7faFdF2642f4C6dF6D0e77184f190289Bc2fc7` |
| AIC 桥 | `0x9a7faFdF2642f4C6dF6D0e77184f190289Bc2fc7` |

***

### 3. 协议状态机与一致性约束

桥协议可抽象为两个确定性状态转换：

1. `DepositInitiated` (源链)\
   资产从 `EOA -> 桥金库`；状态通过事件日志提交并成为跨链意图。
2. `ClaimProcessed` (目标链)\
   在多签验证通过后，目标金库向目标地址释放等值资产。

核心一致性约束：

* **单次花费约束**: `processedClaims[claimId]` 保证每个 `claimId` 只能执行一次。
* **资产守恒约束**： 一个 `认领` 仅在签名和参数完全匹配时执行，防止过度增发/释放。
* **边界约束**: `minAmount` 和 `maxAmount` 适用于两种 `存款` 和 `认领`.
* **运行时安全约束**: `Pausable + ReentrancyGuard` 对关键路径进行门控并阻止重入。

***

### 4. 密码学信任模型（EIP-712 多签）

`认领` 使用带域绑定的 EIP-712 类型化数据签名：

* `name = "AIC-BSC-Bridge"`
* `version = "1"`
* `chainId`
* `verifyingContract`

这从设计上提供了域隔离：相同签名不能在另一条链或合约实例上重放。\
在实现层面，安全通过以下方式强制执行：

* **签名阈值**: `signatures.length >= minSigners` 且签名者必须属于活动验证者集合。
* **重复过滤**： 来自同一验证者的重复签名只计为一次。
* **有效期窗口**: `deadline` 防止在到期后执行。
* **强参数绑定**: `claimId/sourceChainId/token/to/amount/nonce/deadline` 全部被哈希进签名摘要。

***

### 5. 流动性层设计与金库控制

桥合约实际上是单资产金库，流动性控制围绕 `reserveCap`:

* 如果金库余额超过 `reserveCap`，多余部分会被自动清扫到 `coldWallet` 通过 `sweepExcess()`.
* `reserveCap = 0` 为暂时的高流动性窗口禁用自动清扫。
* `setReserveCap` 和 `setColdWallet` 二者在更新后都会触发立即清扫。

该设计将热钱包可用性与冷钱包的风险隔离和长期托管分离开来。

***

### 6. 跨链流程

### 6.1 BSC -> AIC（USDT -> USDI）

1. 用户在 BSC 上批准桥合约的 USDT 授权（`approve`)
2. 用户调用 `deposit(amount, dstChainId=3018, recipient)`
3. 中继者观察到 `DepositInitiated` 并收集验证者签名
4. `认领` 在 AIC 上执行，向接收者释放 USDI
5. 如果接收者在 AIC 的余额低于阈值，可能会应用燃气补贴逻辑（由中继者/API 层处理）

### 6.2 AIC -> BSC（USDI -> USDT）

1. 用户在 AIC 上批准桥合约的 USDI 授权（`approve`)
2. 用户调用 `deposit(amount, dstChainId=56, recipient)`
3. 中继者监控并汇总验证者签名
4. `认领` 在 BSC 上执行，向接收者释放 USDT
5. API 返回该方向的费用详情（见第 8 节）

***

### 7. 桥合约功能（`Bridge.sol`)

### 7.1 核心写入方法

* `deposit(uint256 amount, uint256 dstChainId, address recipient)`
  * 强制范围： `minAmount <= amount <= maxAmount`
  * 通过余额差验证拒绝带转账费的代币
  * 发出事件 `DepositInitiated(...)`
* `claim(Claim c, bytes[] signatures)`
  * 验证 `deadline`, `token`，以及金额边界
  * 验证未处理的 `claimId` （防重放）
  * 使用 EIP-712 签名并验证 `minSigners` 阈值
  * 发出事件 `ClaimProcessed(...)`

### 7.2 治理与风险控制

* `pause()` / `unpause()`： 紧急停止与恢复
* `setValidator()` / `setMinSigners()`： 验证者集合与阈值管理
* `setLimits()`： 更新每笔交易的最小/最大限制
* `setReserveCap()` / `setColdWallet()` / `sweepExcess()`： 自动清扫多余资金
* `emergencyWithdrawNative()` / `emergencyWithdrawERC20()`： 仅在暂停状态下的紧急提取

### 7.3 EIP-712

* 域（Domain）： `name = "AIC-BSC-Bridge"`, `version = "1"`
* 认领字段：
  * `claimId`
  * `sourceChainId`
  * `token`
  * `to`
  * `amount`
  * `nonce`
  * `deadline`

### 7.4 关键代码片段（摘录）

#### A) `存款`： 范围检查 + 拒绝带转账费代币 + 事件提交

```solidity
function deposit(uint256 amount, uint256 dstChainId, address recipient)
    external
    whenNotPaused
    nonReentrant
{
    require(amount > 0, "amount");
    require(amount >= minAmount && amount <= maxAmount, "amount range");
    require(recipient != address(0), "recipient");
    uint256 balBefore = token.balanceOf(address(this));
    token.safeTransferFrom(msg.sender, address(this), amount);
    uint256 balAfter = token.balanceOf(address(this));
    require(balAfter - balBefore == amount, "fee-on-transfer unsupported");
    uint256 id = ++depositNonce;
    emit DepositInitiated(msg.sender, recipient, amount, dstChainId, id);
    _sweepExcess();
}
```

技术要点：

* `balAfter - balBefore == amount` 明确拒绝带转账费的代币以防止记账偏差。
* `depositNonce` 在源链上是单调递增且可按事件索引的。

#### B) `认领`： 防重放 + 类型化数据摘要 + 多签验证

```solidity
function claim(Claim calldata c, bytes[] calldata signatures)
    external
    whenNotPaused
    nonReentrant
{
    require(c.deadline == 0 || block.timestamp <= c.deadline, "expired");
    require(c.token == address(token), "token mismatch");
    require(c.amount > 0, "amount");
    require(c.amount >= minAmount && c.amount <= maxAmount, "amount range");
    require(!processedClaims[c.claimId], "claimed");

    bytes32 digest = _hashTypedDataV4(
        keccak256(abi.encode(
            CLAIM_TYPEHASH,
            c.claimId,
            c.sourceChainId,
            c.token,
            c.to,
            c.amount,
            c.nonce,
            c.deadline
        ))
    );

    _verifySignatures(digest, signatures);
    processedClaims[c.claimId] = true;
    token.safeTransfer(c.to, c.amount);
    emit ClaimProcessed(c.claimId, c.to, c.amount, c.sourceChainId);
}
```

技术要点：

* `processedClaims[c.claimId]` 是协议层面的防重放开关。
* EIP-712 摘要绑定所有业务参数并防止签名迁移攻击。

#### C) `_verifySignatures`： 阈值验证与去重

```solidity
function _verifySignatures(bytes32 digest, bytes[] calldata signatures) internal view {
    require(signatures.length >= minSigners, "few sigs");
    uint256 valid;
    address[] memory seen = new address[](signatures.length);
    for (uint256 i = 0; i < signatures.length; i++) {
        address signer = ECDSA.recover(digest, signatures[i]);
        if (!isValidator[signer]) continue;
        bool dup = false;
        for (uint256 j = 0; j < valid; j++) {
            if (seen[j] == signer) { dup = true; break; }
        }
        if (dup) continue;
        seen[valid] = signer;
        valid++;
        if (valid >= minSigners) return;
    }
    revert("not enough sigs");
}
```

技术要点：

* 签名数量不等于有效签名者数量；只有活跃且唯一的验证者会增加 `valid`.
* 提前返回（`valid >= minSigners`）可降低平均 gas 成本。

***

### 8. 费用规则（API 层）

当前 API 端费用配置：

* `FEE_RATE_PCT = 5`
* `FEE_FIXED_USDI = 1`
* AIC -> BSC 的计算公式：

```
totalFee = (depositAmount * FEE_RATE_PCT / 100) + FEE_FIXED_USDI
```

示例（`1000 USDI`):

```
totalFee = 1000 * 5% + 1 = 51 USDI
```

***

### 9. 交易查询 API

基础 URL：

```
https://bridge-api.aicchain.io/
```

常用端点：

* `GET /api/status`： 服务健康与数据库统计
* `GET /api/tx/bsc/:txHash`： 查询 BSC -> AIC 交易
* `GET /api/tx/aic/:txHash`： 查询 AIC -> BSC 交易
* `GET /api/tx/:txHash`： 自动检测方向
* `GET /api/list/bsc`： 分页的 BSC -> AIC 记录
* `GET /api/list/aic`： 分页的 AIC -> BSC 记录

***

### 10. 故障语义与可观测性

该协议使用可证明故障策略：

* 链上故障通过 `require`原子回退，无任何部分状态写入。
* 跨链路径故障可以通过以下项端到端跟踪 `存款 txHash`, `认领 txHash`，以及 `资金 txHash`.
* 查询 API 由中继者的 SQLite 状态支持，为支持、审计和对账提供稳定的离线索引视图。

推荐的工程指标：

* 端到端 `存款 -> 认领` 延迟百分位（P50/P95/P99）
* 中继者区块滞后与重试队列深度
* 认领失败分布（签名失败、范围失败、余额不足、已过期）


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.aicchain.io/docs-zh/sheng-tai-xi-tong/cross-chain-bridge.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
