Files
assetxContracts/doc/YT资产金库系统操作流程图.md

169 KiB
Raw Blame History

YT资产金库系统操作流程图

目录

  1. 创建Vault流程
  2. 用户存款流程depositYT
  3. 用户提款流程withdrawYT - 两阶段提现)
  4. 价格更新流程
  5. 资产管理流程 - 提取投资
  6. 资产管理流程 - 归还资产
  7. 批量操作流程
  8. 查询信息流程
  9. 暂停功能流程

1. 创建Vault流程

┌─────────────────────────────────────────────────────────────────────┐
│                         Owner (系统管理员)                            │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 调用 createVault()
                             │    name: "YT-A Token"
                             │    symbol: "YT-A"
                             │    manager: 0x123...
                             │    hardCap: 1,000,000 YT
                             │    wusd: 0x7Cd...或0使用默认
                             │    redemptionTime: 2025-02-15 00:00:00
                             │    initialWusdPrice: 1.05e30
                             │    initialYtPrice: 1.05e30
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    YTAssetFactory.sol                                 │
│  ─────────────────────────────────────────────────────────────────  │
│  function createVault(...)                                            │
│                                                                       │
│  权限检查:                                                           │
│  ✓ onlyOwner - 只有Factory owner可以创建                            │
│  ✓ manager != address(0) - 管理员地址有效                           │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 确定硬顶值
                             │    _hardCap == 0 ? defaultHardCap : _hardCap
                             │    → 使用传入的 1,000,000 YT
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      编码初始化数据                                   │
│  ─────────────────────────────────────────────────────────────────  │
│  bytes memory initData = abi.encodeWithSelector(                      │
│      YTAssetVault.initialize.selector,                                │
│      "YT-A Token",                                                    │
│      "YT-A",                                                          │
│      0x123...,              // manager                                │
│      1000000e18,            // hardCap                                │
│      0x7Cd...,              // wusd                                   │
│      1739577600,            // redemptionTime (Unix时间戳)            │
│      1050000000000000000000000000000,  // 1.05e30                    │
│      1050000000000000000000000000000   // 1.05e30                    │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 部署ERC1967代理合约
                             │    new ERC1967Proxy(vaultImplementation, initData)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   部署并初始化YTAssetVault                            │
│  ─────────────────────────────────────────────────────────────────  │
│  新合约地址: 0xVault001...                                            │
│                                                                       │
│  ① __ERC20_init("YT-A Token", "YT-A")                                │
│     • 初始化ERC20代币                                                 │
│     • name: "YT-A Token"                                              │
│     • symbol: "YT-A"                                                  │
│     • decimals: 18                                                    │
│                                                                       │
│  ② __UUPSUpgradeable_init()                                          │
│     • 初始化UUPS升级模式                                              │
│                                                                       │
│  ③ __ReentrancyGuard_init()                                          │
│     • 初始化重入保护                                                  │
│                                                                       │
│  ④ 设置基本参数                                                       │
│     factory = msg.sender (YTAssetFactory地址)                        │
│     manager = 0x123...                                                │
│     hardCap = 1,000,000 * 1e18                                        │
│     wusdAddress = 0x7Cd...                                            │
│                                                                       │
│  ⑤ __Pausable_init()                                                 │
│     • 初始化暂停功能(默认未暂停)                                    │
│                                                                       │
│  ⑥ 设置价格精度1e30                                               │
│     wusdPrice = 1.05e30  (初始价格1.05)                              │
│     ytPrice = 1.05e30    (初始价格1.05)                              │
│                                                                       │
│  ⑦ 设置赎回时间                                                       │
│     nextRedemptionTime = 1739577600 (2025-02-15)                     │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 4. 记录到Factory
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      Factory状态更新                                  │
│  ─────────────────────────────────────────────────────────────────  │
│  allVaults.push(0xVault001...)                                        │
│  isVault[0xVault001...] = true                                       │
│                                                                       │
│  触发事件:                                                           │
│  emit VaultCreated(                                                   │
│      0xVault001...,                                                   │
│      0x123...,           // manager                                   │
│      "YT-A Token",                                                    │
│      "YT-A",                                                          │
│      1000000e18,         // hardCap                                   │
│      0                   // index                                     │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 5. 返回vault地址
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         创建完成                                      │
│  ─────────────────────────────────────────────────────────────────  │
│  返回值: 0xVault001...                                                │
│                                                                       │
│  Vault状态                                                          │
│  • totalSupply: 0                                                     │
│  • totalAssets: 0 WUSD                                                │
│  • wusdPrice: 1.05 (精度1e30)                                        │
│  • ytPrice: 1.05 (精度1e30)                                          │
│  • hardCap: 1,000,000 YT                                              │
│  • nextRedemptionTime: 2025-02-15 00:00:00                           │
│  • 可接受用户存款 ✓                                                   │
└─────────────────────────────────────────────────────────────────────┘

2. 用户存款流程depositYT

┌─────────────────────────────────────────────────────────────────────┐
│                         用户 (User)                                   │
│  持有: 10,000 WUSD                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 0. 预览操作(可选)
                             │    调用 previewBuy(10000e18)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      YTAssetVault.sol                                 │
│  ─────────────────────────────────────────────────────────────────  │
│  function previewBuy(10000e18) returns (uint256 ytAmount)             │
│                                                                       │
│  计算逻辑:                                                           │
│  ytAmount = (wusdAmount × wusdPrice) ÷ ytPrice                       │
│           = (10,000 × 1.05e30) ÷ 1.05e30                             │
│           = 10,000 YT                                                 │
│                                                                       │
│  返回预览结果: 10,000 YT                                              │
└─────────────────────────────────────────────────────────────────────┘
                             │
                             │ 1. 授权WUSD给Vault
                             │    WUSD.approve(vault, 10000e18)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      WUSD授权检查                                     │
│  ✓ allowance[user][vault] >= 10,000 WUSD                             │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 调用 depositYT(10000e18)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    YTAssetVault.depositYT()                           │
│  ─────────────────────────────────────────────────────────────────  │
│  function depositYT(uint256 _wusdAmount)                              │
│      • 非重入保护: nonReentrant                                       │
│      • 暂停检查: whenNotPaused                                        │
│      • 参数: 10,000 WUSD                                              │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 参数验证
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                        参数检查                                       │
│  ─────────────────────────────────────────────────────────────────  │
│  ① _wusdAmount > 0                                                    │
│     ✓ 10,000 > 0 通过                                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 4. 计算可获得的YT数量
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      计算YT数量                                       │
│  ─────────────────────────────────────────────────────────────────  │
│  公式ytAmount = (wusdAmount × wusdPrice) ÷ ytPrice                 │
│                                                                       │
│  当前价格:                                                           │
│  • wusdPrice = 1.05e30                                                │
│  • ytPrice = 1.05e30                                                  │
│                                                                       │
│  计算过程:                                                           │
│  ytAmount = (10,000e18 × 1.05e30) ÷ 1.05e30                          │
│           = 10,000e18                                                 │
│           = 10,000 YT                                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 5. 检查硬顶限制
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      硬顶检查                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  if (hardCap > 0 && totalSupply() + ytAmount > hardCap)              │
│      revert HardCapExceeded()                                         │
│                                                                       │
│  当前状态:                                                           │
│  • hardCap = 1,000,000 YT                                             │
│  • totalSupply() = 0 YT (首次存款)                                   │
│  • ytAmount = 10,000 YT                                               │
│  • 0 + 10,000 = 10,000 ≤ 1,000,000  ✓ 通过                          │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 6. 转入WUSDCEI模式 - Checks完成
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      代币转移Effects                              │
│  ─────────────────────────────────────────────────────────────────  │
│  IERC20(wusdAddress).safeTransferFrom(                                │
│      msg.sender,           // 用户地址                                │
│      address(this),        // Vault地址                               │
│      10000e18              // 转入10,000 WUSD                         │
│  )                                                                    │
│                                                                       │
│  结果:                                                               │
│  • 用户WUSD余额: 10,000 → 0                                          │
│  • Vault WUSD余额: 0 → 10,000                                        │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 7. 铸造YT代币给用户
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      铸造YT代币                                       │
│  ─────────────────────────────────────────────────────────────────  │
│  _mint(msg.sender, 10000e18)                                          │
│                                                                       │
│  ERC20铸造                                                          │
│  • balanceOf[user] += 10,000 YT                                       │
│  • totalSupply += 10,000 YT                                           │
│                                                                       │
│  结果:                                                               │
│  • 用户YT余额: 0 → 10,000 YT                                         │
│  • 总供应量: 0 → 10,000 YT                                           │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 8. 触发事件
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      事件记录Interactions                         │
│  ─────────────────────────────────────────────────────────────────  │
│  emit Buy(                                                            │
│      msg.sender,           // 用户地址                                │
│      10000e18,             // WUSD数量                                │
│      10000e18              // YT数量                                  │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 9. 返回YT数量
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         存款完成                                      │
│  ─────────────────────────────────────────────────────────────────  │
│  用户最终状态:                                                       │
│  • WUSD余额: 0                                                        │
│  • YT余额: 10,000 YT                                                  │
│                                                                       │
│  Vault最终状态                                                      │
│  • totalSupply: 10,000 YT                                             │
│  • totalAssets: 10,000 WUSD                                           │
│  • idleAssets: 10,000 WUSD                                            │
│  • managedAssets: 0 WUSD                                              │
│                                                                       │
│  返回值: 10,000 YT                                                    │
└─────────────────────────────────────────────────────────────────────┘

3. 用户提款流程withdrawYT - 两阶段提现)

3.1 第一阶段:提交提现请求

┌─────────────────────────────────────────────────────────────────────┐
│                         用户 (User)                                   │
│  持有: 5,000 YT                                                       │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 0. 预览操作(可选)
                             │    调用 previewSell(5000e18)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      YTAssetVault.sol                                 │
│  ─────────────────────────────────────────────────────────────────  │
│  function previewSell(5000e18) returns (uint256 wusdAmount)           │
│                                                                       │
│  计算逻辑:                                                           │
│  wusdAmount = (ytAmount × ytPrice) ÷ wusdPrice                       │
│             = (5,000 × 1.05e30) ÷ 1.05e30                            │
│             = 5,000 WUSD                                              │
│                                                                       │
│  返回预览结果: 5,000 WUSD                                             │
└─────────────────────────────────────────────────────────────────────┘
                             │
                             │ 1. 检查赎回时间(可选)
                             │    调用 canRedeemNow()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      赎回时间检查                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  function canRedeemNow() returns (bool)                               │
│      return block.timestamp >= nextRedemptionTime                     │
│                                                                       │
│  检查:                                                               │
│  • 当前时间: 2025-02-16 10:00:00 (1739692800)                        │
│  • 赎回时间: 2025-02-15 00:00:00 (1739577600)                        │
│  • 1739692800 >= 1739577600  ✓ 可以赎回                             │
│                                                                       │
│  getTimeUntilNextRedemption() = 0 秒                                  │
└─────────────────────────────────────────────────────────────────────┘
                             │
                             │ 2. 调用 withdrawYT(5000e18)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                YTAssetVault.withdrawYT() - 提交请求                   │
│  ─────────────────────────────────────────────────────────────────  │
│  function withdrawYT(uint256 _ytAmount) returns (uint256 requestId)  │
│      • 非重入保护: nonReentrant                                       │
│      • 暂停检查: whenNotPaused                                        │
│      • 参数: 5,000 YT                                                 │
│                                                                       │
│  🔴 重要变化此函数不再立即发放WUSD                                │
│     只创建提现请求,进入排队等待                                      │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 多重验证
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                        参数检查                                       │
│  ─────────────────────────────────────────────────────────────────  │
│  ① _ytAmount > 0                                                      │
│     ✓ 5,000 > 0 通过                                                  │
│                                                                       │
│  ② balanceOf(msg.sender) >= _ytAmount                                │
│     ✓ 10,000 >= 5,000 通过                                            │
│     (用户持有足够的YT)                                                │
│                                                                       │
│  ③ block.timestamp >= nextRedemptionTime                             │
│     ✓ 2025-02-16 >= 2025-02-15 通过                                  │
│     (已到赎回时间)                                                    │
│                                                                       │
│  ⚠️  不再检查流动性即使vault中WUSD不足也可以提交请求               │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 4. 计算应得的WUSD数量
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      计算WUSD数量                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  公式wusdAmount = (ytAmount × ytPrice) ÷ wusdPrice                 │
│                                                                       │
│  假设价格已更新:                                                     │
│  • wusdPrice = 1.00e30  (WUSD价格回落到1.0)                          │
│  • ytPrice = 1.10e30    (YT价格上涨到1.1)                            │
│                                                                       │
│  计算过程:                                                           │
│  wusdAmount = (5,000e18 × 1.10e30) ÷ 1.00e30                         │
│             = 5,500e18                                                │
│             = 5,500 WUSD                                              │
│                                                                       │
│  💡 这个金额会锁定在请求中,不受后续价格变化影响                      │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 5. 立即销毁YT代币CEI - Effects
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      销毁YT代币                                       │
│  ─────────────────────────────────────────────────────────────────  │
│  _burn(msg.sender, 5000e18)                                           │
│                                                                       │
│  ERC20销毁                                                          │
│  • balanceOf[user] -= 5,000 YT                                        │
│  • totalSupply -= 5,000 YT                                            │
│                                                                       │
│  结果:                                                               │
│  • 用户YT余额: 10,000 → 5,000 YT                                     │
│  • 总供应量: 10,000 → 5,000 YT                                       │
│                                                                       │
│  ⚠️  注意YT已销毁但WUSD还未发放                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 6. 创建提现请求记录
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      创建WithdrawRequest                              │
│  ─────────────────────────────────────────────────────────────────  │
│  requestId = requestIdCounter  // 当前假设为 requestId = 42          │
│                                                                       │
│  withdrawRequests[42] = WithdrawRequest({                             │
│      user: msg.sender,              // 用户地址                       │
│      ytAmount: 5000e18,             // 5,000 YT                       │
│      wusdAmount: 5500e18,           // 应得5,500 WUSD                 │
│      requestTime: block.timestamp,  // 当前时间戳                     │
│      queueIndex: 42,                // 队列位置                       │
│      processed: false               // 未处理                         │
│  })                                                                   │
│                                                                       │
│  userRequestIds[msg.sender].push(42)  // 记录到用户请求列表          │
│  requestIdCounter++                    // 43                          │
│  pendingRequestsCount++                // 待处理计数+1                │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 7. 触发事件
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      事件记录                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  emit WithdrawRequestCreated(                                         │
│      42,                   // requestId                               │
│      msg.sender,           // 用户地址                                │
│      5000e18,              // YT数量                                  │
│      5500e18,              // 应得WUSD数量                            │
│      42                    // queueIndex                              │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 8. 返回请求ID
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     请求提交完成                                      │
│  ─────────────────────────────────────────────────────────────────  │
│  返回值: requestId = 42                                               │
│                                                                       │
│  用户当前状态:                                                       │
│  • YT余额: 5,000 YT (已减少)                                          │
│  • WUSD余额: 0 WUSD (尚未到账) ⏳                                     │
│  • 提现请求: requestId = 42 (排队中)                                  │
│                                                                       │
│  Vault状态                                                          │
│  • totalSupply: 5,000 YT (已减少)                                    │
│  • pendingRequestsCount: +1                                           │
│  • requestIdCounter: 43                                               │
│                                                                       │
│  📍 下一步:                                                          │
│  用户需要等待Manager或Factory调用processBatchWithdrawals()           │
│  批量处理提现请求后WUSD才会到账                                     │
│                                                                       │
│  查询请求状态:                                                       │
│  • getRequestDetails(42) - 查看请求详情                              │
│  • getUserPendingRequests(user) - 查看所有待处理请求                 │
│  • getQueueProgress() - 查看队列处理进度                             │
└─────────────────────────────────────────────────────────────────────┘

3.2 第二阶段:批量处理提现请求

┌─────────────────────────────────────────────────────────────────────┐
│                Manager/Factory (资产管理方)                           │
│  当前状态:                                                           │
│  • Vault中有足够的WUSD (基金赎回资金已到账)                          │
│  • 待处理请求: 150个                                                  │
│  • 准备批量发放WUSD给用户                                             │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 查询队列状态(可选)
                             │    getQueueProgress()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      查询队列进度                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  function getQueueProgress() returns (                                │
│      uint256 currentIndex,     // 当前处理到的位置: 100              │
│      uint256 totalRequests,    // 总请求数: 250                      │
│      uint256 pendingRequests   // 待处理数: 150                      │
│  )                                                                    │
│                                                                       │
│  状态信息:                                                           │
│  • 已处理: 100个请求                                                  │
│  • 待处理: 150个请求                                                  │
│  • 处理进度: 100/250 = 40%                                            │
└─────────────────────────────────────────────────────────────────────┘
                             │
                             │ 2. 调用 processBatchWithdrawals(50)
                             │    每批处理50个请求
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│            YTAssetVault.processBatchWithdrawals()                     │
│  ─────────────────────────────────────────────────────────────────  │
│  function processBatchWithdrawals(uint256 _batchSize)                 │
│      returns (uint256 processedCount, uint256 totalDistributed)      │
│                                                                       │
│  参数:                                                               │
│  • _batchSize: 50 (本批次最多处理50个)                               │
│                                                                       │
│  权限检查:                                                           │
│  • msg.sender == manager ✓  或                                        │
│  • msg.sender == factory ✓                                            │
│                                                                       │
│  保护机制:                                                           │
│  • nonReentrant - 重入保护                                            │
│  • whenNotPaused - 暂停检查                                           │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 验证批次大小
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      参数检查                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  if (_batchSize == 0) revert InvalidBatchSize()                      │
│  ✓ 50 > 0 通过                                                        │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 4. 获取可用WUSD并开始循环处理
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      循环处理请求                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  uint256 availableWUSD = vault.balance(WUSD)  // 假设: 100,000 WUSD  │
│  uint256 processedCount = 0                                           │
│  uint256 totalDistributed = 0                                         │
│                                                                       │
│  for (i = processedUpToIndex; i < requestIdCounter; i++) {           │
│      if (processedCount >= _batchSize) break  // 达到批次限制        │
│                                                                       │
│      WithdrawRequest storage request = withdrawRequests[i]           │
│                                                                       │
│      if (request.processed) continue  // 跳过已处理的                │
│                                                                       │
│      if (availableWUSD >= request.wusdAmount) {                      │
│          // ✅ 可以处理此请求                                         │
│          处理逻辑 ▼                                                   │
│      } else {                                                         │
│          // ❌ WUSD不足停止处理                                     │
│          break                                                        │
│      }                                                                │
│  }                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 5. 处理单个请求(循环内)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      处理请求详细步骤                                 │
│  ─────────────────────────────────────────────────────────────────  │
│  以 requestId = 42 为例:                                             │
│                                                                       │
│  ① 转账WUSD给用户                                                     │
│     IERC20(wusd).safeTransfer(request.user, 5500e18)                 │
│     • 用户WUSD余额: 0 → 5,500 WUSD ✅                                │
│                                                                       │
│  ② 标记为已处理                                                       │
│     request.processed = true                                          │
│                                                                       │
│  ③ 更新统计数据                                                       │
│     availableWUSD -= 5500e18      // 剩余可用WUSD减少                │
│     totalDistributed += 5500e18    // 累计发放增加                    │
│     processedCount++               // 处理计数+1                      │
│     pendingRequestsCount--         // 待处理计数-1                    │
│                                                                       │
│  ④ 触发事件                                                           │
│     emit WithdrawRequestProcessed(42, user, 5500e18)                 │
│                                                                       │
│  然后继续处理下一个请求...                                            │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 6. 更新处理进度指针
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      更新processedUpToIndex                           │
│  ─────────────────────────────────────────────────────────────────  │
│  if (processedCount > 0) {                                            │
│      // 找到下一个未处理的位置                                        │
│      for (i = processedUpToIndex; i < requestIdCounter; i++) {       │
│          if (!withdrawRequests[i].processed) {                       │
│              processedUpToIndex = i                                   │
│              break                                                    │
│          }                                                            │
│      }                                                                │
│  }                                                                    │
│                                                                       │
│  更新结果:                                                           │
│  • processedUpToIndex: 100 → 150                                     │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 7. 触发批次处理事件
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      批次处理完成事件                                 │
│  ─────────────────────────────────────────────────────────────────  │
│  emit BatchProcessed(                                                 │
│      100,                  // startIndex (开始位置)                   │
│      150,                  // endIndex (结束位置)                     │
│      50,                   // processedCount (实际处理数量)           │
│      275000e18             // totalDistributed (总发放WUSD)           │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 8. 返回处理结果
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                     批量处理完成                                      │
│  ─────────────────────────────────────────────────────────────────  │
│  返回值:                                                             │
│  • processedCount: 50 (处理了50个请求)                               │
│  • totalDistributed: 275,000 WUSD (总共发放)                         │
│                                                                       │
│  更新后的状态:                                                       │
│  • pendingRequestsCount: 150 → 100 (还剩100个待处理)                 │
│  • processedUpToIndex: 100 → 150                                     │
│  • Vault WUSD余额: 100,000 → (100,000 - 275,000) = -175,000 ❌      │
│    (这里假设vault有足够资金实际会提前检查)                         │
│                                                                       │
│  用户影响requestId = 42的用户                                   │
│  ✅ YT余额: 5,000 YT (已销毁)                                         │
│  ✅ WUSD余额: 5,500 WUSD (已到账!)                                  │
│  ✅ 提现完成可以自由使用WUSD                                        │
│                                                                       │
│  队列状态:                                                           │
│  • 已处理: 150/250 = 60%                                              │
│  • 待处理: 100个                                                      │
│  • 可继续调用processBatchWithdrawals()处理剩余请求                   │
└─────────────────────────────────────────────────────────────────────┘

3.3 资金不足时的处理

┌─────────────────────────────────────────────────────────────────────┐
│                      场景WUSD资金不足                               │
│  ─────────────────────────────────────────────────────────────────  │
│  当前状态:                                                           │
│  • Vault中WUSD: 50,000                                                │
│  • 待处理请求: 100个                                                  │
│  • 前10个请求需要: 60,000 WUSD                                        │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 调用 processBatchWithdrawals(100)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      处理过程                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  循环处理:                                                           │
│  • Request 1: 需要5,000 WUSD ✅ 处理成功 (剩余45,000)                │
│  • Request 2: 需要5,000 WUSD ✅ 处理成功 (剩余40,000)                │
│  • Request 3: 需要5,000 WUSD ✅ 处理成功 (剩余35,000)                │
│  • Request 4: 需要5,000 WUSD ✅ 处理成功 (剩余30,000)                │
│  • Request 5: 需要5,000 WUSD ✅ 处理成功 (剩余25,000)                │
│  • Request 6: 需要5,000 WUSD ✅ 处理成功 (剩余20,000)                │
│  • Request 7: 需要5,000 WUSD ✅ 处理成功 (剩余15,000)                │
│  • Request 8: 需要5,000 WUSD ✅ 处理成功 (剩余10,000)                │
│  • Request 9: 需要5,000 WUSD ✅ 处理成功 (剩余5,000)                 │
│  • Request 10: 需要5,000 WUSD ✅ 处理成功 (剩余0)                    │
│  • Request 11: 需要5,000 WUSD ❌ 资金不足,停止处理                  │
│                                                                       │
│  处理结果:                                                           │
│  • processedCount: 10 (只处理了10个而不是100个)                    │
│  • totalDistributed: 50,000 WUSD                                     │
│  • 剩余90个请求继续排队                                               │
│                                                                       │
│  ⚠️  不会revert优雅地停止                                         │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 后续处理
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      等待资金到账                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  Manager操作                                                        │
│  ① 等待基金赎回下一批资金到账                                        │
│  ② 调用 depositManagedAssets(100000e18) 充值                        │
│  ③ 再次调用 processBatchWithdrawals(100) 继续处理                   │
│                                                                       │
│  用户体验:                                                           │
│  • Request 1-10的用户: ✅ WUSD已到账                                 │
│  • Request 11+的用户: ⏳ 继续排队等待                                │
│  • 可通过getUserPendingRequests()查询状态                            │
└─────────────────────────────────────────────────────────────────────┘

4. 价格更新流程

┌─────────────────────────────────────────────────────────────────────┐
│                    Oracle / Manager                                   │
│  接收到最新价格数据:                                                 │
│  • WUSD价格: $1.02                                                    │
│  • YT-A价格: $1.15                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 方式1: Manager直接更新
                             │ 调用 vault.updatePrices()
                             │
                             │ 方式2: Factory批量更新
                             │ 调用 factory.updateVaultPrices()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    YTAssetVault.updatePrices()                        │
│  ─────────────────────────────────────────────────────────────────  │
│  function updatePrices(                                               │
│      uint256 _wusdPrice,   // 1.02e30                                 │
│      uint256 _ytPrice      // 1.15e30                                 │
│  ) external onlyManager                                               │
│                                                                       │
│  权限检查:                                                           │
│  • msg.sender == manager ✓  或                                        │
│  • msg.sender == factory ✓                                            │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 价格验证
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      价格有效性检查                                   │
│  ─────────────────────────────────────────────────────────────────  │
│  if (_wusdPrice == 0 || _ytPrice == 0)                                │
│      revert InvalidPrice()                                            │
│                                                                       │
│  检查:                                                               │
│  • _wusdPrice = 1.02e30 ≠ 0  ✓                                       │
│  • _ytPrice = 1.15e30 ≠ 0  ✓                                         │
│                                                                       │
│  注意:                                                               │
│  • 价格必须 > 0                                                       │
│  • 价格精度为1e30                                                     │
│  • 没有时间间隔限制,可随时更新                                       │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 更新价格状态
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      更新存储状态                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  wusdPrice = _wusdPrice                                               │
│  ytPrice = _ytPrice                                                   │
│                                                                       │
│  更新前:                                                             │
│  • wusdPrice: 1.05e30 → 1.02e30  (下降2.86%)                         │
│  • ytPrice: 1.05e30 → 1.15e30    (上涨9.52%)                         │
│                                                                       │
│  影响:                                                               │
│  ① 后续depositYT计算变化                                             │
│     ytAmount = wusdAmount × 1.02 / 1.15                              │
│     → 用户用相同WUSD获得更少YT                                        │
│                                                                       │
│  ② 后续withdrawYT计算变化                                            │
│     wusdAmount = ytAmount × 1.15 / 1.02                              │
│     → 用户用相同YT获得更多WUSD                                        │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 触发事件
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      事件记录                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  emit PriceUpdated(                                                   │
│      1020000000000000000000000000000,  // wusdPrice                  │
│      1150000000000000000000000000000,  // ytPrice                    │
│      1739692800                         // timestamp                  │
│  )                                                                    │
│                                                                       │
│  链下监听:                                                           │
│  • 前端可监听此事件更新UI显示                                         │
│  • 用户可看到最新的兑换比率                                           │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 4. 完成更新
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         更新完成                                      │
│  ─────────────────────────────────────────────────────────────────  │
│  当前兑换比率示例:                                                   │
│                                                                       │
│  存款 (depositYT):                                                    │
│  • 1,000 WUSD → (1,000 × 1.02) / 1.15 = 886.96 YT                    │
│                                                                       │
│  提款 (withdrawYT):                                                   │
│  • 1,000 YT → (1,000 × 1.15) / 1.02 = 1,127.45 WUSD                  │
│                                                                       │
│  YT持有者收益                                                       │
│  • 价格从1.05到1.15增值9.52%                                       │
│  • 持有1,000 YT相当于价值1,127.45 WUSD                               │
└─────────────────────────────────────────────────────────────────────┘

5. 资产管理流程 - 提取投资

┌─────────────────────────────────────────────────────────────────────┐
│                    Manager (资产管理员)                               │
│  计划: 提取50,000 WUSD进行外部投资                                   │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 调用 withdrawForManagement()
                             │    _to: manager地址
                             │    _amount: 50,000 WUSD
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│              YTAssetVault.withdrawForManagement()                     │
│  ─────────────────────────────────────────────────────────────────  │
│  function withdrawForManagement(                                      │
│      address _to,          // 0x123... (manager)                      │
│      uint256 _amount       // 50,000 WUSD                             │
│  ) external onlyManager nonReentrant whenNotPaused                    │
│                                                                       │
│  权限检查:                                                           │
│  ✓ onlyManager - 只有manager可调用                                   │
│  ✓ nonReentrant - 重入保护                                            │
│  ✓ whenNotPaused - 暂停检查                                           │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 参数验证
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      验证检查                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  ① if (_amount == 0) revert InvalidAmount()                          │
│     ✓ 50,000 > 0 通过                                                 │
│                                                                       │
│  ② uint256 availableAssets = vault.balance(WUSD)                     │
│     if (_amount > availableAssets) revert InvalidAmount()            │
│                                                                       │
│     Vault当前状态                                                   │
│     • totalAssets: 100,000 WUSD                                       │
│     • idleAssets: 100,000 WUSD (全部在vault中)                       │
│     • managedAssets: 0 WUSD                                           │
│                                                                       │
│     检查:                                                            │
│     • availableAssets = 100,000 WUSD                                  │
│     • 50,000 ≤ 100,000  ✓ 通过                                       │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 更新managedAssetsCEI - Effects
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      状态更新                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  managedAssets += _amount                                             │
│                                                                       │
│  更新:                                                               │
│  • managedAssets: 0 → 50,000 WUSD                                    │
│                                                                       │
│  重要说明:                                                           │
│  managedAssets记录了被管理员提取、正在进行外部投资的WUSD数量         │
│  这部分资产不在vault合约中但仍计入totalAssets                       │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 4. 转出WUSDInteractions
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      代币转移                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  IERC20(wusdAddress).safeTransfer(                                    │
│      _to,                  // manager地址                             │
│      50000e18              // 50,000 WUSD                             │
│  )                                                                    │
│                                                                       │
│  转账结果:                                                           │
│  • Vault WUSD余额: 100,000 → 50,000 WUSD                             │
│  • Manager WUSD余额: +50,000 WUSD                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 5. 触发事件
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      事件记录                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  emit AssetsWithdrawn(                                                │
│      0x123...,             // manager地址                             │
│      50000e18              // 提取数量                                │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 6. 提取完成
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         提取完成                                      │
│  ─────────────────────────────────────────────────────────────────  │
│  Vault最终状态                                                      │
│  • totalAssets(): 100,000 WUSD (不变!)                               │
│    计算: idleAssets + managedAssets                                   │
│         = 50,000 + 50,000 = 100,000                                   │
│                                                                       │
│  • idleAssets(): 50,000 WUSD                                          │
│    (vault合约实际持有的WUSD)                                          │
│                                                                       │
│  • managedAssets: 50,000 WUSD                                         │
│    (manager正在管理的WUSD)                                            │
│                                                                       │
│  • totalSupply: 100,000 YT (不变)                                    │
│                                                                       │
│  用户影响:                                                           │
│  ✓ totalAssets不变YT价值不受影响                                   │
│  ✓ 用户依然持有相同价值的YT份额                                       │
│  ✗ 暂时无法提款流动性不足需等待manager归还                      │
│                                                                       │
│  Manager后续操作                                                    │
│  → 用50,000 WUSD进行DeFi投资                                         │
│  → 赚取收益                                                           │
│  → 通过depositManagedAssets归还                                      │
└─────────────────────────────────────────────────────────────────────┘

6. 资产管理流程 - 归还资产

┌─────────────────────────────────────────────────────────────────────┐
│                    Manager (资产管理员)                               │
│  投资收益情况:                                                       │
│  • 提取: 50,000 WUSD                                                  │
│  • 投资收益: +5,000 WUSD                                              │
│  • 准备归还: 55,000 WUSD (本金+利润)                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 授权WUSD给Vault
                             │    WUSD.approve(vault, 55000e18)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      WUSD授权检查                                     │
│  ✓ allowance[manager][vault] >= 55,000 WUSD                          │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 调用 depositManagedAssets()
                             │    _amount: 55,000 WUSD
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│              YTAssetVault.depositManagedAssets()                      │
│  ─────────────────────────────────────────────────────────────────  │
│  function depositManagedAssets(                                       │
│      uint256 _amount       // 55,000 WUSD                             │
│  ) external onlyManager nonReentrant whenNotPaused                    │
│                                                                       │
│  权限检查:                                                           │
│  ✓ onlyManager - 只有manager可调用                                   │
│  ✓ nonReentrant - 重入保护                                            │
│  ✓ whenNotPaused - 暂停检查                                           │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 参数验证
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      验证检查                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  if (_amount == 0) revert InvalidAmount()                            │
│  ✓ 55,000 > 0 通过                                                    │
│                                                                       │
│  当前Vault状态                                                      │
│  • idleAssets: 50,000 WUSD                                            │
│  • managedAssets: 50,000 WUSD                                         │
│  • totalAssets: 100,000 WUSD                                          │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 4. 更新managedAssetsCEI - Effects
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      状态更新(关键逻辑)                             │
│  ─────────────────────────────────────────────────────────────────  │
│  if (_amount >= managedAssets) {                                     │
│      // 归还金额 >= 提取金额清零managedAssets                      │
│      managedAssets = 0                                                │
│  } else {                                                             │
│      // 归还金额 < 提取金额,部分归还                                │
│      managedAssets -= _amount                                         │
│  }                                                                    │
│                                                                       │
│  本例计算:                                                           │
│  • _amount = 55,000 WUSD                                              │
│  • managedAssets = 50,000 WUSD                                        │
│  • 55,000 >= 50,000 ✓ 进入第一个分支                                │
│  • managedAssets = 0                                                  │
│                                                                       │
│  多余的5,000 WUSD如何处理                                          │
│  → 自动增加到vault余额成为利润                                     │
│  → totalAssets会增加                                                  │
│  → 所有YT持有者共享这部分收益                                        │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 5. 转入WUSDInteractions
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      代币转移                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  IERC20(wusdAddress).safeTransferFrom(                                │
│      msg.sender,           // manager地址                             │
│      address(this),        // vault地址                               │
│      55000e18              // 55,000 WUSD                             │
│  )                                                                    │
│                                                                       │
│  转账结果:                                                           │
│  • Manager WUSD余额: -55,000 WUSD                                    │
│  • Vault WUSD余额: 50,000 → 105,000 WUSD                             │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 6. 触发事件
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      事件记录                                         │
│  ─────────────────────────────────────────────────────────────────  │
│  emit AssetsDeposited(                                                │
│      55000e18              // 归还数量                                │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 7. 归还完成
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         归还完成                                      │
│  ─────────────────────────────────────────────────────────────────  │
│  Vault最终状态                                                      │
│  • totalAssets(): 105,000 WUSD (增加了5,000!)                        │
│    计算: idleAssets + managedAssets                                   │
│         = 105,000 + 0 = 105,000                                       │
│                                                                       │
│  • idleAssets(): 105,000 WUSD                                         │
│    (vault合约实际持有的WUSD包含收益)                                │
│                                                                       │
│  • managedAssets: 0 WUSD                                              │
│    (所有资产已归还)                                                   │
│                                                                       │
│  • totalSupply: 100,000 YT (不变)                                    │
│                                                                       │
│  收益分配:                                                           │
│  • 投资收益: 5,000 WUSD                                               │
│  • 收益率: 5,000 / 50,000 = 10%                                       │
│  • 每个YT的价值提升:                                                  │
│    之前: 100,000 WUSD / 100,000 YT = 1.0 WUSD/YT                     │
│    现在: 105,000 WUSD / 100,000 YT = 1.05 WUSD/YT                    │
│                                                                       │
│  用户影响:                                                           │
│  ✓ 所有YT持有者自动获得5%增值                                         │
│  ✓ 可以提款了(流动性恢复)                                           │
│  ✓ 如果用户提取YT会按1.05的比例获得更多WUSD                        │
│                                                                       │
│  示例:                                                               │
│  用户持有10,000 YT提取时可获得                                    │
│  (10,000 × 1.05 WUSD/YT) = 10,500 WUSD                               │
│  相比初始存入的10,000 WUSD获利500 WUSD (5%)                        │
└─────────────────────────────────────────────────────────────────────┘

7. 批量操作流程

7.1 批量创建Vault

┌─────────────────────────────────────────────────────────────────────┐
│                         Owner (系统管理员)                            │
│  计划: 批量创建3个不同的YT Vault                                      │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 调用 createVaultBatch()
                             │ • names: ["YT-A", "YT-B", "YT-C"]
                             │ • symbols: ["YTA", "YTB", "YTC"]
                             │ • managers: [0x111, 0x222, 0x333]
                             │ • hardCaps: [1000000e18, 500000e18, 2000000e18]
                             │ • wusd: 0x7Cd...
                             │ • redemptionTimes: [time1, time2, time3]
                             │ • initialWusdPrices: [1.05e30, 1.05e30, 1.05e30]
                             │ • initialYtPrices: [1.05e30, 1.02e30, 1.10e30]
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                YTAssetFactory.createVaultBatch()                      │
│  ─────────────────────────────────────────────────────────────────  │
│  1. 参数长度验证                                                      │
│     require(所有数组长度相等)                                         │
│     ✓ 所有数组长度都是3                                               │
│                                                                       │
│  2. 循环创建                                                          │
│     for (i = 0; i < 3; i++) {                                         │
│         vaults[i] = this.createVault(...)                             │
│     }                                                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ├─────────┬─────────┐
                             │         │         │
         第1个Vault          │     第2个Vault    │     第3个Vault
              ▼              │         ▼         │         ▼
┌───────────────────┐  ┌───────────────────┐  ┌───────────────────┐
│ YT-A Token        │  │ YT-B Token        │  │ YT-C Token        │
│ Symbol: YTA       │  │ Symbol: YTB       │  │ Symbol: YTC       │
│ Manager: 0x111    │  │ Manager: 0x222    │  │ Manager: 0x333    │
│ HardCap: 1M YT    │  │ HardCap: 500K YT  │  │ HardCap: 2M YT    │
│ YT Price: 1.05    │  │ YT Price: 1.02    │  │ YT Price: 1.10    │
│ 地址: 0xVault001  │  │ 地址: 0xVault002  │  │ 地址: 0xVault003  │
└───────────────────┘  └───────────────────┘  └───────────────────┘
                             │         │         │
                             └─────────┴─────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         批量创建完成                                  │
│  ─────────────────────────────────────────────────────────────────  │
│  返回值: [0xVault001, 0xVault002, 0xVault003]                        │
│                                                                       │
│  Factory状态                                                        │
│  • allVaults.length: 3                                                │
│  • isVault[0xVault001] = true                                        │
│  • isVault[0xVault002] = true                                        │
│  • isVault[0xVault003] = true                                        │
│                                                                       │
│  优势:                                                               │
│  ✓ 一次交易创建多个vault节省gas                                    │
│  ✓ 原子操作,全部成功或全部失败                                       │
│  ✓ 统一管理多个资产池                                                 │
└─────────────────────────────────────────────────────────────────────┘

7.2 批量更新价格

┌─────────────────────────────────────────────────────────────────────┐
│                    Oracle / Owner                                     │
│  接收到3个vault的最新价格数据                                         │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 调用 updateVaultPricesBatch()
                             │ • vaults: [0xVault001, 0xVault002, 0xVault003]
                             │ • wusdPrices: [1.02e30, 1.03e30, 1.01e30]
                             │ • ytPrices: [1.15e30, 1.08e30, 1.20e30]
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│             YTAssetFactory.updateVaultPricesBatch()                   │
│  ─────────────────────────────────────────────────────────────────  │
│  1. 参数验证                                                          │
│     require(数组长度相等)                                             │
│     ✓ 所有数组长度都是3                                               │
│                                                                       │
│  2. 循环更新                                                          │
│     for (i = 0; i < 3; i++) {                                         │
│         YTAssetVault(vaults[i]).updatePrices(                         │
│             wusdPrices[i],                                            │
│             ytPrices[i]                                               │
│         )                                                             │
│         emit PricesUpdated(vaults[i], wusdPrices[i], ytPrices[i])    │
│     }                                                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ├─────────┬─────────┐
                             │         │         │
         Vault001            │     Vault002      │     Vault003
         价格更新            │      价格更新     │      价格更新
              ▼              │         ▼         │         ▼
┌───────────────────┐  ┌───────────────────┐  ┌───────────────────┐
│ WUSD: 1.02        │  │ WUSD: 1.03        │  │ WUSD: 1.01        │
│ YT: 1.15          │  │ YT: 1.08          │  │ YT: 1.20          │
│ 涨幅: +9.52%      │  │ 涨幅: +2.88%      │  │ 涨幅: +9.09%      │
└───────────────────┘  └───────────────────┘  └───────────────────┘
                             │         │         │
                             └─────────┴─────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         批量更新完成                                  │
│  ─────────────────────────────────────────────────────────────────  │
│  优势:                                                               │
│  ✓ 一次交易更新多个vault价格                                         │
│  ✓ 节省gas费用                                                        │
│  ✓ 确保所有vault价格同时更新                                         │
│  ✓ 适合定时任务批量更新                                               │
│                                                                       │
│  触发的事件:                                                         │
│  • PricesUpdated × 3                                                  │
│  • PriceUpdated × 3 (从各个vault)                                    │
└─────────────────────────────────────────────────────────────────────┘

7.3 批量设置赎回时间

┌─────────────────────────────────────────────────────────────────────┐
│                         Owner (系统管理员)                            │
│  统一设置赎回时间: 2025-03-15 00:00:00                               │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 调用 setVaultNextRedemptionTimeBatch()
                             │ • vaults: [0xVault001, 0xVault002, 0xVault003]
                             │ • nextRedemptionTime: 1741996800
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│        YTAssetFactory.setVaultNextRedemptionTimeBatch()               │
│  ─────────────────────────────────────────────────────────────────  │
│  for (i = 0; i < vaults.length; i++) {                                │
│      YTAssetVault(vaults[i]).setNextRedemptionTime(                   │
│          _nextRedemptionTime                                          │
│      )                                                                │
│      emit NextRedemptionTimeSet(vaults[i], _nextRedemptionTime)      │
│  }                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                         批量设置完成                                  │
│  ─────────────────────────────────────────────────────────────────  │
│  所有3个vault的赎回时间都设置为:                                      │
│  2025-03-15 00:00:00                                                  │
│                                                                       │
│  用户影响:                                                           │
│  ✓ 所有vault的用户在同一天可以赎回                                    │
│  ✓ 统一管理赎回周期                                                   │
│  ✓ 类似基金的统一开放日                                               │
└─────────────────────────────────────────────────────────────────────┘

8. 查询信息流程

8.1 查询单个Vault信息

┌─────────────────────────────────────────────────────────────────────┐
│                    前端应用 / 查询者                                  │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 调用 vault.getVaultInfo()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                  YTAssetVault.getVaultInfo()                          │
│  ─────────────────────────────────────────────────────────────────  │
│  function getVaultInfo() returns (                                    │
│      uint256 _totalAssets,                                            │
│      uint256 _idleAssets,                                             │
│      uint256 _managedAssets,                                          │
│      uint256 _totalSupply,                                            │
│      uint256 _hardCap,                                                │
│      uint256 _wusdPrice,                                              │
│      uint256 _ytPrice,                                                │
│      uint256 _nextRedemptionTime                                      │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 读取状态
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      返回完整信息                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  返回示例:                                                           │
│  {                                                                    │
│      totalAssets: 105000e18,        // 105,000 WUSD                  │
│      idleAssets: 105000e18,         // 105,000 WUSD                  │
│      managedAssets: 0,              // 0 WUSD                        │
│      totalSupply: 100000e18,        // 100,000 YT                    │
│      hardCap: 1000000e18,           // 1,000,000 YT                  │
│      wusdPrice: 1020000000000000000000000000000,  // 1.02            │
│      ytPrice: 1150000000000000000000000000000,    // 1.15            │
│      nextRedemptionTime: 1739577600  // 2025-02-15 00:00:00         │
│  }                                                                    │
│                                                                       │
│  计算衍生指标:                                                       │
│  • 每YT价值: 105,000 / 100,000 = 1.05 WUSD                           │
│  • 资金利用率: (105,000 - 0) / 105,000 = 100%                        │
│  • 硬顶使用率: 100,000 / 1,000,000 = 10%                             │
│  • 当前兑换率: 1 WUSD = 1.02/1.15 = 0.887 YT                         │
└─────────────────────────────────────────────────────────────────────┘

8.2 通过Factory查询Vault信息

┌─────────────────────────────────────────────────────────────────────┐
│                    前端应用 / 查询者                                  │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 调用 factory.getVaultInfo(vaultAddress)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│               YTAssetFactory.getVaultInfo()                           │
│  ─────────────────────────────────────────────────────────────────  │
│  function getVaultInfo(address _vault) returns (                      │
│      bool exists,                                                     │
│      uint256 totalAssets,                                             │
│      uint256 idleAssets,                                              │
│      uint256 managedAssets,                                           │
│      uint256 totalSupply,                                             │
│      uint256 hardCap,                                                 │
│      uint256 wusdPrice,                                               │
│      uint256 ytPrice,                                                 │
│      uint256 nextRedemptionTime                                       │
│  )                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 检查vault是否存在
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      存在性检查                                       │
│  ─────────────────────────────────────────────────────────────────  │
│  exists = isVault[_vault]                                             │
│  if (!exists) return (false, 0, 0, 0, 0, 0, 0, 0, 0)                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 调用vault获取信息
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      返回完整信息                                     │
│  ─────────────────────────────────────────────────────────────────  │
│  {                                                                    │
│      exists: true,                   // ✓ vault存在                  │
│      totalAssets: 105000e18,                                          │
│      idleAssets: 105000e18,                                           │
│      managedAssets: 0,                                                │
│      totalSupply: 100000e18,                                          │
│      hardCap: 1000000e18,                                             │
│      wusdPrice: 1020000000000000000000000000000,                     │
│      ytPrice: 1150000000000000000000000000000,                       │
│      nextRedemptionTime: 1739577600                                   │
│  }                                                                    │
│                                                                       │
│  优势:                                                               │
│  ✓ 通过factory统一查询                                                │
│  ✓ 可验证vault是否为合法vault                                        │
│  ✓ 一次调用获取所有信息                                               │
└─────────────────────────────────────────────────────────────────────┘

8.3 查询所有Vault列表

┌─────────────────────────────────────────────────────────────────────┐
│                    前端应用 / 查询者                                  │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 获取总数量
                             │    factory.getVaultCount()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      获取Vault总数                                    │
│  ─────────────────────────────────────────────────────────────────  │
│  function getVaultCount() returns (uint256)                           │
│  return allVaults.length                                              │
│                                                                       │
│  返回: 3 (有3个vault)                                                 │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 获取所有vault地址
                             │    factory.getAllVaults()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      获取所有Vault地址                                │
│  ─────────────────────────────────────────────────────────────────  │
│  function getAllVaults() returns (address[] memory)                   │
│  return allVaults                                                     │
│                                                                       │
│  返回: [0xVault001, 0xVault002, 0xVault003]                          │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 或分页查询
                             │    factory.getVaults(0, 2)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      分页查询Vault地址                                │
│  ─────────────────────────────────────────────────────────────────  │
│  function getVaults(uint256 _start, uint256 _end)                     │
│                                                                       │
│  参数:                                                                │
│  • _start: 0 (起始索引)                                               │
│  • _end: 2 (结束索引,不包含)                                         │
│                                                                       │
│  返回: [0xVault001, 0xVault002]                                      │
│                                                                       │
│  优势:                                                               │
│  ✓ 适合vault数量很多时的分页加载                                      │
│  ✓ 减少单次调用的gas消耗                                              │
│  ✓ 改善前端加载性能                                                   │
└─────────────────────────────────────────────────────────────────────┘

8.4 查询提现请求信息(新增)

┌─────────────────────────────────────────────────────────────────────┐
│                    用户 / 前端应用                                    │
│  需求:查询提现请求的状态                                             │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ├──────────────┬──────────────┬──────────────┐
                             │              │              │              │
                    方式1: 查询单个请求   方式2: 查询用户请求   方式3: 查询队列进度
                             │              │              │              │
                             ▼              ▼              ▼              ▼
┌─────────────────────┐ ┌─────────────────────┐ ┌─────────────────────┐
│ getRequestDetails   │ │getUserRequestIds    │ │ getQueueProgress    │
│ (requestId)         │ │(userAddress)        │ │()                   │
└──────────┬──────────┘ └──────────┬──────────┘ └──────────┬──────────┘
           │                       │                       │
           ▼                       ▼                       ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      方式1: 查询单个请求详情                          │
│  ─────────────────────────────────────────────────────────────────  │
│  function getRequestDetails(uint256 _requestId)                       │
│      returns (WithdrawRequest memory)                                 │
│                                                                       │
│  输入: requestId = 42                                                 │
│                                                                       │
│  返回:                                                                │
│  {                                                                    │
│      user: 0xUser123...,                                              │
│      ytAmount: 5000e18,         // 提现的YT数量                       │
│      wusdAmount: 5500e18,       // 应得WUSD数量                       │
│      requestTime: 1739692800,   // 请求时间戳                         │
│      queueIndex: 42,            // 队列位置                           │
│      processed: false           // 是否已处理                         │
│  }                                                                    │
│                                                                       │
│  前端展示:                                                           │
│  ┌────────────────────────────────────────┐                          │
│  │ 📋 提现请求 #42                         │                          │
│  │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │                          │
│  │ 状态: ⏳ 排队中                         │                          │
│  │ YT数量: 5,000 YT                       │                          │
│  │ 应得WUSD: 5,500 WUSD                   │                          │
│  │ 提交时间: 2025-02-16 10:00:00          │                          │
│  │ 队列位置: 第42位                        │                          │
│  └────────────────────────────────────────┘                          │
└─────────────────────────────────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      方式2: 查询用户所有请求                          │
│  ─────────────────────────────────────────────────────────────────  │
│  步骤1: 获取用户的请求ID列表                                          │
│  function getUserRequestIds(address _user)                            │
│      returns (uint256[] memory)                                       │
│                                                                       │
│  返回: [15, 42, 68] (用户有3个请求)                                   │
│                                                                       │
│  步骤2: 获取用户待处理的请求                                          │
│  function getUserPendingRequests(address _user)                       │
│      returns (WithdrawRequest[] memory)                               │
│                                                                       │
│  返回: 只返回 processed = false 的请求                                │
│  [                                                                    │
│      {                                                                │
│          user: 0xUser123...,                                          │
│          ytAmount: 5000e18,                                           │
│          wusdAmount: 5500e18,                                         │
│          requestTime: 1739692800,                                     │
│          queueIndex: 42,                                              │
│          processed: false                                             │
│      }                                                                │
│  ]                                                                    │
│                                                                       │
│  前端展示:                                                           │
│  ┌────────────────────────────────────────┐                          │
│  │ 👤 我的提现请求                         │                          │
│  │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │                          │
│  │ ✅ 请求#15  1,000 YT → 1,100 WUSD      │                          │
│  │    状态: 已完成  2025-02-10            │                          │
│  │                                        │                          │
│  │ ⏳ 请求#42  5,000 YT → 5,500 WUSD      │                          │
│  │    状态: 排队中  队列第42位            │                          │
│  │    提交于: 2025-02-16 10:00            │                          │
│  │                                        │                          │
│  │ ⏳ 请求#68  3,000 YT → 3,300 WUSD      │                          │
│  │    状态: 排队中  队列第68位            │                          │
│  │    提交于: 2025-02-16 15:30            │                          │
│  └────────────────────────────────────────┘                          │
└─────────────────────────────────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      方式3: 查询队列处理进度                          │
│  ─────────────────────────────────────────────────────────────────  │
│  function getQueueProgress() returns (                                │
│      uint256 currentIndex,                                            │
│      uint256 totalRequests,                                           │
│      uint256 pendingRequests                                          │
│  )                                                                    │
│                                                                       │
│  返回示例:                                                            │
│  {                                                                    │
│      currentIndex: 38,          // 当前处理到第38个                   │
│      totalRequests: 150,        // 总共150个请求                      │
│      pendingRequests: 112       // 还有112个待处理                    │
│  }                                                                    │
│                                                                       │
│  衍生计算:                                                            │
│  • 已处理: 38个                                                       │
│  • 处理进度: 38/150 = 25.3%                                           │
│  • 待处理: 112个                                                      │
│                                                                       │
│  前端展示:                                                           │
│  ┌────────────────────────────────────────┐                          │
│  │ 🔄 提现处理进度                         │                          │
│  │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │                          │
│  │ [████████░░░░░░░░░░░░░░░] 25.3%       │                          │
│  │                                        │                          │
│  │ 已处理: 38 / 150                       │                          │
│  │ 待处理: 112个请求                       │                          │
│  │ 当前位置: 第38位                        │                          │
│  │                                        │                          │
│  │ 💡 提示:                               │                          │
│  │ 您的请求#42在第42位前面还有4个请求    │                          │
│  │ 预计等待时间: 约5分钟                   │                          │
│  └────────────────────────────────────────┘                          │
│                                                                       │
│  优势:                                                               │
│  ✓ 实时查看全局处理进度                                               │
│  ✓ 估算自己的等待时间                                                 │
│  ✓ O(1)查询gas友好                                                  │
└─────────────────────────────────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                      方式4: 查询待处理总数                            │
│  ─────────────────────────────────────────────────────────────────  │
│  function getPendingRequestsCount() returns (uint256)                 │
│                                                                       │
│  返回: 112 (还有112个待处理)                                          │
│                                                                       │
│  特点:                                                               │
│  • O(1)复杂度,实时维护的计数器                                       │
│  • 不需要循环避免gas爆炸                                            │
│  • 可用于前端显示统计信息                                             │
│                                                                       │
│  前端展示:                                                           │
│  ┌────────────────────────────────────────┐                          │
│  │ 📊 系统统计                             │                          │
│  │ ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │                          │
│  │ 待处理提现: 112个                       │                          │
│  │ Vault余额: 50,000 WUSD                 │                          │
│  │ 预计可处理: 约45个请求                  │                          │
│  └────────────────────────────────────────┘                          │
└─────────────────────────────────────────────────────────────────────┘

附录:重要概念说明

A. 价格精度 (PRICE_PRECISION)

精度: 1e30 (10^30)

示例:
• 价格 1.0 表示为: 1000000000000000000000000000000 (1e30)
• 价格 1.05 表示为: 1050000000000000000000000000000 (1.05e30)
• 价格 0.98 表示为: 980000000000000000000000000000 (0.98e30)

为什么使用1e30而不是1e18
✓ 更高的精度,减少舍入误差
✓ 适合复杂的价格计算
✓ 支持更精确的价格波动

B. 兑换计算公式

存款 (depositYT):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
ytAmount = (wusdAmount × wusdPrice) ÷ ytPrice

示例:
• 存入1,000 WUSD
• wusdPrice = 1.05e30
• ytPrice = 1.10e30
• ytAmount = (1,000 × 1.05) ÷ 1.10 = 954.55 YT


提款 (withdrawYT):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
wusdAmount = (ytAmount × ytPrice) ÷ wusdPrice

示例:
• 提取1,000 YT
• ytPrice = 1.10e30
• wusdPrice = 1.05e30
• wusdAmount = (1,000 × 1.10) ÷ 1.05 = 1,047.62 WUSD

C. 资产状态计算

Vault资产状态
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
totalAssets = idleAssets + managedAssets

• idleAssets: vault合约中实际持有的WUSD
• managedAssets: manager提取、正在投资的WUSD
• totalAssets: 用户可赎回的总价值

示例:
vault余额: 50,000 WUSD
managedAssets: 50,000 WUSD
totalAssets: 100,000 WUSD (不变)

用户持有10,000 YT价值:
(10,000 / 100,000) × 100,000 = 10,000 WUSD

D. 硬顶机制

硬顶 (Hard Cap):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
限制YT代币的最大供应量

作用:
✓ 控制vault规模
✓ 风险管理
✓ 防止过度铸造

检查时机:
• 每次depositYT时检查
• if (totalSupply + ytAmount > hardCap) revert

动态调整:
• Factory owner可以通过setHardCap调整
• 但不能低于当前totalSupply

E. 统一赎回时间

赎回时间 (nextRedemptionTime):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
所有用户统一的赎回开放时间

特点:
✓ 类似基金的开放日
✓ 所有用户同时可赎回
✓ 不是个人锁定期

检查:
• block.timestamp >= nextRedemptionTime
• 未到时间调用withdrawYT会revert

管理:
• Factory owner可以设置
• 支持批量设置多个vault

F. CEI模式

CEI模式 (Checks-Effects-Interactions):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
安全的合约编写模式,防止重入攻击

1. Checks (检查)
   • 验证参数
   • 检查权限
   • 检查余额

2. Effects (状态更新)
   • 更新合约状态
   • 修改余额
   • 记录变化

3. Interactions (外部交互)
   • 转账代币
   • 调用外部合约
   • 触发事件

配合nonReentrant modifier确保安全

G. UUPS升级模式

UUPS (Universal Upgradeable Proxy Standard):
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
可升级合约的标准实现方式

结构:
┌─────────────┐
│ ERC1967Proxy│  ← 用户交互的地址(不变)
└──────┬──────┘
       │ delegatecall
       ▼
┌─────────────┐
│ Implementation│  ← 逻辑合约(可升级)
└─────────────┘

优势:
✓ 合约地址不变
✓ 状态数据保留
✓ 可以修复bug和添加功能
✓ 升级权限由Factory控制

注意:
• 不能在状态变量声明时初始化
• 必须使用initialize函数
• 保留__gap数组用于未来扩展

H. 两阶段提现机制Withdraw Queue

两阶段提现机制:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
解决资金分批到账的提现排队问题

设计目的:
• 基金赎回需要时间,资金不会一次性到账
• 按用户提现请求时间先后排队FIFO
• 资金到账后由后端统一批量发放

阶段一:用户提交请求
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
用户调用 withdrawYT(_ytAmount)

执行内容:
1. 验证参数和赎回时间
2. 立即销毁用户的YT代币
3. 计算应得WUSD数量锁定当前价格
4. 创建WithdrawRequest记录
5. 返回requestId供用户查询

关键特点:
✓ YT立即销毁防止重复提现
✓ WUSD暂不发放等待批量处理
✓ 金额已锁定(不受后续价格变化影响)
✓ 即使vault资金不足也可提交请求

阶段二:批量处理发放
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Manager/Factory调用 processBatchWithdrawals(_batchSize)

执行内容:
1. 获取vault当前可用WUSD
2. 按requestId顺序FIFO处理请求
3. 依次给用户转账WUSD
4. 标记请求为已处理
5. 资金不足时自动停止

关键特点:
✓ FIFO严格保证先提交先处理
✓ 支持分批处理避免gas超限
✓ 断点续传(记录处理进度)
✓ 资金不足不会revert优雅停止

数据结构:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
struct WithdrawRequest {
    address user;           // 用户地址
    uint256 ytAmount;       // YT数量
    uint256 wusdAmount;     // 应得WUSD数量锁定
    uint256 requestTime;    // 请求时间
    uint256 queueIndex;     // 队列位置
    bool processed;         // 是否已处理
}

状态变量:
• withdrawRequests[requestId] - 所有请求记录
• userRequestIds[user] - 用户的请求ID列表
• requestIdCounter - 请求ID计数器递增
• processedUpToIndex - 已处理到的位置
• pendingRequestsCount - 待处理请求数O(1)查询)

查询功能:
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
• getUserRequestIds(user) - 用户的所有请求ID
• getRequestDetails(requestId) - 请求详情
• getUserPendingRequests(user) - 用户待处理请求
• getPendingRequestsCount() - 待处理总数
• getQueueProgress() - 队列处理进度

优势:
✓ 解决资金分批到账问题
✓ 公平的FIFO排队机制
✓ Gas优化计数器避免循环
✓ 用户体验好(可查询状态)
✓ 管理灵活(支持分批处理)

使用场景:
1. 基金赎回需要T+1或T+N到账
2. 资金分多批次回流
3. 避免流动性挤兑
4. 统一管理提现流程

风险控制:
⚠️ YT已销毁但WUSD未到账的风险
   → 解决Manager有责任及时处理请求
   → 解决Factory可以代为处理
   
⚠️ 用户长时间等待的风险
   → 解决:可查询队列进度
   → 解决:前端显示预计等待时间
   
⚠️ 价格锁定可能错失市场波动
   → 解决:这是设计特性,确保公平性

9. 暂停功能流程

9.1 暂停单个Vault

┌─────────────────────────────────────────────────────────────────────┐
│                    Factory Owner (紧急情况)                           │
│  检测到: YT-A Vault 存在安全问题                                      │
└────────────────────────────────┬────────────────────────────────────┘
                                 │
                                 │ 1. 调用 pauseVault(vaultAddress)
                                 ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   YTAssetFactory.pauseVault()                         │
│  ─────────────────────────────────────────────────────────────────  │
│  function pauseVault(address _vault) external onlyOwner               │
│                                                                       │
│  权限检查:                                                           │
│  ✓ onlyOwner - 只有Factory owner可调用                              │
│  ✓ isVault[_vault] - 验证vault存在                                  │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 调用 vault.pause()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                    YTAssetVault.pause()                               │
│  ─────────────────────────────────────────────────────────────────  │
│  internal _pause()                                                    │
│      • 设置 paused = true                                             │
│      • 触发 Paused 事件                                               │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 暂停生效
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                        Vault已暂停                                    │
│  ─────────────────────────────────────────────────────────────────  │
│  被阻止的操作revert EnforcedPause                               │
│    ✗ depositYT() - 用户无法存款                                      │
│    ✗ withdrawYT() - 用户无法提款                                     │
│    ✗ withdrawForManagement() - Manager无法提取资产                   │
│    ✗ depositManagedAssets() - Manager无法归还资产                    │
│                                                                       │
│  仍可用的操作:                                                       │
│    ✓ balanceOf() - 查询余额                                          │
│    ✓ totalSupply() - 查询总供应                                     │
│    ✓ totalAssets() - 查询总资产                                     │
│    ✓ getVaultInfo() - 查询详细信息                                  │
│    ✓ previewBuy() - 预览存款                                         │
│    ✓ previewSell() - 预览提款                                        │
│    ✓ canRedeemNow() - 检查赎回状态                                   │
│                                                                       │
│  用户影响:                                                           │
│    • 所有资金操作暂停                                                 │
│    • 资产安全锁定                                                     │
│    • 可以查看但无法操作                                               │
└─────────────────────────────────────────────────────────────────────┘

9.2 恢复单个Vault

┌─────────────────────────────────────────────────────────────────────┐
│                    Factory Owner (问题已解决)                         │
│  安全问题已修复,可以恢复正常运行                                     │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 调用 unpauseVault(vaultAddress)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                  YTAssetFactory.unpauseVault()                        │
│  ─────────────────────────────────────────────────────────────────  │
│  function unpauseVault(address _vault) external onlyOwner             │
│                                                                       │
│  权限检查:                                                           │
│  ✓ onlyOwner - 只有Factory owner可调用                              │
│  ✓ isVault[_vault] - 验证vault存在                                  │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 2. 调用 vault.unpause()
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                   YTAssetVault.unpause()                              │
│  ─────────────────────────────────────────────────────────────────  │
│  internal _unpause()                                                  │
│      • 设置 paused = false                                            │
│      • 触发 Unpaused 事件                                             │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 3. 恢复完成
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                       Vault恢复正常                                   │
│  ─────────────────────────────────────────────────────────────────  │
│  所有功能恢复:                                                       │
│    ✓ depositYT() - 用户可以存款                                      │
│    ✓ withdrawYT() - 用户可以提款(如已过赎回时间)                   │
│    ✓ withdrawForManagement() - Manager可以提取资产                   │
│    ✓ depositManagedAssets() - Manager可以归还资产                    │
│                                                                       │
│  系统状态:                                                           │
│    • 所有操作恢复正常                                                 │
│    • 用户资产未受影响                                                 │
│    • 暂停期间的价格更新仍然有效                                       │
└─────────────────────────────────────────────────────────────────────┘

9.3 批量暂停Vaults

┌─────────────────────────────────────────────────────────────────────┐
│                    Factory Owner (系统级紧急)                         │
│  检测到系统性风险需要暂停多个Vault                                  │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 调用 pauseVaultBatch(vaultAddresses)
                             │    vaults: [0xVault001, 0xVault002, 0xVault003]
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                 YTAssetFactory.pauseVaultBatch()                      │
│  ─────────────────────────────────────────────────────────────────  │
│  function pauseVaultBatch(address[] memory _vaults)                   │
│                                                                       │
│  批量处理:                                                           │
│  for (i = 0; i < _vaults.length; i++) {                               │
│      require(isVault[_vaults[i]])  // 验证每个vault                  │
│      YTAssetVault(_vaults[i]).pause()                                 │
│  }                                                                    │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ├─────────┬─────────┐
                             │         │         │
         Vault001            │     Vault002      │     Vault003
         暂停                │      暂停         │      暂停
              ▼              │         ▼         │         ▼
┌───────────────────┐  ┌───────────────────┐  ┌───────────────────┐
│ YT-A Vault        │  │ YT-B Vault        │  │ YT-C Vault        │
│ 状态: PAUSED      │  │ 状态: PAUSED      │  │ 状态: PAUSED      │
│ 所有操作冻结      │  │ 所有操作冻结      │  │ 所有操作冻结      │
└───────────────────┘  └───────────────────┘  └───────────────────┘
                             │         │         │
                             └─────────┴─────────┘
                                      │
                                      ▼
┌─────────────────────────────────────────────────────────────────────┐
│                       批量暂停完成                                    │
│  ─────────────────────────────────────────────────────────────────  │
│  优势:                                                               │
│  ✓ 一次交易暂停多个vault                                            │
│  ✓ 节省gas费用                                                        │
│  ✓ 原子操作,全部成功或全部失败                                       │
│  ✓ 快速响应系统性风险                                                 │
│                                                                       │
│  系统影响:                                                           │
│  • 所有指定vault的资金操作立即冻结                                    │
│  • 用户资产安全保护                                                   │
│  • 管理员可以调查和修复问题                                           │
└─────────────────────────────────────────────────────────────────────┘

9.4 批量恢复Vaults

┌─────────────────────────────────────────────────────────────────────┐
│                    Factory Owner (风险已消除)                         │
│  问题已解决恢复所有暂停的Vault                                      │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             │ 1. 调用 unpauseVaultBatch(vaultAddresses)
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                YTAssetFactory.unpauseVaultBatch()                     │
│  ─────────────────────────────────────────────────────────────────  │
│  批量恢复所有vault                                                    │
│  • 验证每个vault存在                                                  │
│  • 调用每个vault的unpause()                                           │
│  • 原子操作执行                                                       │
└────────────────────────────┬────────────────────────────────────────┘
                             │
                             ▼
┌─────────────────────────────────────────────────────────────────────┐
│                       系统全面恢复                                    │
│  ─────────────────────────────────────────────────────────────────  │
│  所有vault恢复正常运行                                                │
│  用户可以继续所有操作                                                 │
└─────────────────────────────────────────────────────────────────────┘

暂停功能的应用场景:

┌─────────────────────────────────────────────────────────────────────┐
│                      使用场景和最佳实践                               │
│                                                                       │
│  何时使用暂停功能:                                                   │
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │
│                                                                       │
│  1⃣  安全漏洞发现                                                    │
│     • 发现合约安全问题                                                │
│     • 暂停受影响的vault                                               │
│     • 保护用户资产                                                    │
│     • 修复后恢复                                                      │
│                                                                       │
│  2⃣  价格异常                                                        │
│     • 价格预言机故障                                                  │
│     • 价格剧烈波动                                                    │
│     • 暂停交易防止损失                                                │
│     • 价格稳定后恢复                                                  │
│                                                                       │
│  3⃣  系统升级                                                        │
│     • 准备合约升级                                                    │
│     • 暂停所有操作                                                    │
│     • 执行升级                                                        │
│     • 验证后恢复                                                      │
│                                                                       │
│  4⃣  流动性危机                                                      │
│     • Manager提取资金后未及时归还                                     │
│     • 暂停提款防止挤兑                                                │
│     • 等待资金回流                                                    │
│     • 流动性恢复后解除                                                │
│                                                                       │
│  5⃣  监管要求                                                        │
│     • 配合监管调查                                                    │
│     • 临时冻结操作                                                    │
│     • 保留完整记录                                                    │
│                                                                       │
│  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━  │
│                                                                       │
│  最佳实践:                                                           │
│  ✓ 暂停前公告(如有时间)                                            │
│  ✓ 记录暂停原因                                                      │
│  ✓ 快速调查和修复                                                    │
│  ✓ 恢复前全面测试                                                    │
│  ✓ 恢复后公告说明                                                    │
│                                                                       │
│  注意事项:                                                           │
│  ⚠️  暂停不影响已持有的资产价值                                       │
│  ⚠️  暂停期间价格仍可更新由Factory                                │
│  ⚠️  Manager在暂停期间也无法操作                                      │
│  ⚠️  查询功能不受影响                                                 │
└─────────────────────────────────────────────────────────────────────┘