diff --git a/document/Vault金库系统操作流程文档.md b/document/Vault金库系统操作流程文档.md
new file mode 100644
index 0000000..969cc65
--- /dev/null
+++ b/document/Vault金库系统操作流程文档.md
@@ -0,0 +1,1184 @@
+Vault金库系统操作流程文档
+目录
+1. [创建Vault流程](#1-创建vault流程)
+2. [用户存款流程(depositYT)](#2-用户存款流程deposityt)
+3. [用户提款流程(withdrawYT)](#3-用户提款流程withdrawyt)
+4. [价格更新流程](#4-价格更新流程)
+5. [资产管理流程 - 提取投资](#5-资产管理流程---提取投资)
+6. [资产管理流程 - 归还资产](#6-资产管理流程---归还资产)
+7. [批量操作流程](#7-批量操作流程)
+8. [查询信息流程](#8-查询信息流程)
+
+1. 创建Vault流程
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 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... │
+│ │
+│ ⑤ 设置价格(精度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)
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户 (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 │
+│ • 参数: 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. 转入WUSD(CEI模式 - 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)
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户 (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) │
+│ • 非重入保护: nonReentrant │
+│ • 参数: 5,000 YT │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 3. 多重验证
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 参数检查 │
+│ ───────────────────────────────────────────────────────────────── │
+│ ① _ytAmount > 0 │
+│ ✓ 5,000 > 0 通过 │
+│ │
+│ ② balanceOf(msg.sender) >= _ytAmount │
+│ ✓ 10,000 >= 5,000 通过 │
+│ (用户持有足够的YT) │
+│ │
+│ ③ block.timestamp >= nextRedemptionTime │
+│ ✓ 2025-02-16 >= 2025-02-15 通过 │
+│ (已到赎回时间) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 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,000e18 × 1.10) ÷ 1.00 │
+│ = 5,500e18 │
+│ = 5,500 WUSD │
+│ │
+│ 用户获得收益: 5,500 - 5,000 = 500 WUSD (10%增值) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 5. 检查Vault流动性
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 流动性检查 │
+│ ───────────────────────────────────────────────────────────────── │
+│ uint256 availableWUSD = IERC20(wusdAddress).balanceOf(vault) │
+│ if (wusdAmount > availableWUSD) revert InsufficientWUSD() │
+│ │
+│ 当前状态: │
+│ • Vault中WUSD余额: 10,000 WUSD │
+│ • 需要支付: 5,500 WUSD │
+│ • 5,500 ≤ 10,000 ✓ 流动性充足 │
+│ │
+│ 注意: │
+│ 如果manager已提取部分资金进行投资,availableWUSD可能不足 │
+│ 此时用户需要等待manager归还资金 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 6. 销毁用户的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 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 7. 转出WUSD给用户
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 代币转移(Interactions) │
+│ ───────────────────────────────────────────────────────────────── │
+│ IERC20(wusdAddress).safeTransfer( │
+│ msg.sender, // 用户地址 │
+│ 5500e18 // 转出5,500 WUSD │
+│ ) │
+│ │
+│ 结果: │
+│ • Vault WUSD余额: 10,000 → 4,500 │
+│ • 用户WUSD余额: 0 → 5,500 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 8. 触发事件
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 事件记录 │
+│ ───────────────────────────────────────────────────────────────── │
+│ emit Sell( │
+│ msg.sender, // 用户地址 │
+│ 5000e18, // YT数量 │
+│ 5500e18 // WUSD数量 │
+│ ) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 9. 返回WUSD数量
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 提款完成 │
+│ ───────────────────────────────────────────────────────────────── │
+│ 用户最终状态: │
+│ • YT余额: 5,000 YT (剩余) │
+│ • WUSD余额: 5,500 WUSD (获得) │
+│ • 收益: 500 WUSD (10%增值) │
+│ │
+│ Vault最终状态: │
+│ • totalSupply: 5,000 YT │
+│ • totalAssets: 4,500 WUSD (假设无managedAssets) │
+│ • idleAssets: 4,500 WUSD │
+│ │
+│ 返回值: 5,500 WUSD │
+└─────────────────────────────────────────────────────────────────────┘
+
+4. 价格更新流程
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 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. 资产管理流程 - 提取投资
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 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 │
+│ │
+│ 权限检查: │
+│ ✓ onlyManager - 只有manager可调用 │
+│ ✓ nonReentrant - 重入保护 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 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. 更新managedAssets(CEI - Effects)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 状态更新 │
+│ ───────────────────────────────────────────────────────────────── │
+│ managedAssets += _amount │
+│ │
+│ 更新: │
+│ • managedAssets: 0 → 50,000 WUSD │
+│ │
+│ 重要说明: │
+│ managedAssets记录了被管理员提取、正在进行外部投资的WUSD数量 │
+│ 这部分资产不在vault合约中,但仍计入totalAssets │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 4. 转出WUSD(Interactions)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 代币转移 │
+│ ───────────────────────────────────────────────────────────────── │
+│ 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. 资产管理流程 - 归还资产
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 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 │
+│ │
+│ 权限检查: │
+│ ✓ onlyManager - 只有manager可调用 │
+│ ✓ nonReentrant - 重入保护 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 3. 参数验证
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 验证检查 │
+│ ───────────────────────────────────────────────────────────────── │
+│ if (_amount == 0) revert InvalidAmount() │
+│ ✓ 55,000 > 0 通过 │
+│ │
+│ 当前Vault状态: │
+│ • idleAssets: 50,000 WUSD │
+│ • managedAssets: 50,000 WUSD │
+│ • totalAssets: 100,000 WUSD │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 4. 更新managedAssets(CEI - 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. 转入WUSD(Interactions)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 代币转移 │
+│ ───────────────────────────────────────────────────────────────── │
+│ 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
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 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 批量更新价格
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 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 批量设置赎回时间
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 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信息
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 前端应用 / 查询者 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 调用 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信息
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 前端应用 / 查询者 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 调用 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列表
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 前端应用 / 查询者 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 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消耗 │
+│ ✓ 改善前端加载性能 │
+└─────────────────────────────────────────────────────────────────────┘
+
+附录:重要概念说明
+A. 价格精度 (PRICE_PRECISION)
+Plain Text
+精度: 1e30 (10^30)
+
+示例:
+• 价格 1.0 表示为: 1000000000000000000000000000000 (1e30)
+• 价格 1.05 表示为: 1050000000000000000000000000000 (1.05e30)
+• 价格 0.98 表示为: 980000000000000000000000000000 (0.98e30)
+
+为什么使用1e30而不是1e18?
+✓ 更高的精度,减少舍入误差
+✓ 适合复杂的价格计算
+✓ 支持更精确的价格波动
+B. 兑换计算公式
+Plain Text
+存款 (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. 资产状态计算
+Plain Text
+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. 硬顶机制
+Plain Text
+硬顶 (Hard Cap):
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+限制YT代币的最大供应量
+
+作用:
+✓ 控制vault规模
+✓ 风险管理
+✓ 防止过度铸造
+
+检查时机:
+• 每次depositYT时检查
+• if (totalSupply + ytAmount > hardCap) revert
+
+动态调整:
+• Factory owner可以通过setHardCap调整
+• 但不能低于当前totalSupply
+E. 统一赎回时间
+Plain Text
+赎回时间 (nextRedemptionTime):
+━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
+所有用户统一的赎回开放时间
+
+特点:
+✓ 类似基金的开放日
+✓ 所有用户同时可赎回
+✓ 不是个人锁定期
+
+检查:
+• block.timestamp >= nextRedemptionTime
+• 未到时间调用withdrawYT会revert
+
+管理:
+• Factory owner可以设置
+• 支持批量设置多个vault
+
diff --git a/document/ytLp池子合约流程文档.md b/document/ytLp池子合约流程文档.md
new file mode 100644
index 0000000..f9a8993
--- /dev/null
+++ b/document/ytLp池子合约流程文档.md
@@ -0,0 +1,551 @@
+ytLp池子合约流程文档
+1. 项目概述
+1.1 设计目标
+基于GMX GLP原理,设计一个支持多种YT(Yield Token)代币的流动性池系统。
+1.2 架构对比
+Plain Text
+GMX GLP池子: YT流动性池:
+├─ ETH ├─ YT-A
+├─ WBTC ├─ YT-B
+├─ USDC ├─ YT-C
+├─ USDT ├─ YT-D
+└─ DAI └─ WUSD
+ ↓ ↓
+以USDG统一计价 以USDY统一计价
+核心特点:
+Markdown
+- 一篮子YT代币: YT-A, YT-B, YT-C等(不同的收益代币)
+- WUSD代币支持: 支持WUSD稳定币(地址: `0x7Cd017ca5ddb86861FA983a34b5F495C6F898c41`)
+- 统一底层: 所有YT都基于USDC
+- LP代币(ytLP): 代表用户在池子中的份额
+- Swap功能: YT-A ↔ YT-B ↔ YT-C ↔ WUSD
+- 计价单位: USDY(完全模拟GMX的USDG)
+- 动态手续费: 根据池子占比自动调整手续费
+- 自动复利: 手续费直接留在池子中,ytLP价值自动增长
+2. 系统流程图
+Plain Text
+┌─────────────────────────────────────────┐
+│ 用户交互层 │
+│ YTRewardRouter.sol │
+│ (addLiquidity / removeLiquidity) │
+└──────────────┬──────────────────────────┘
+ │
+ ┌───────────┴─────────────┐
+ ▼ ▼
+┌───────────────┐ ┌──────────────────┐
+│ YTPoolManager │◄── │ YTVault │
+│ (流动性管理) │ │ (资金池+动态费率) │
+└───────┬───────┘ └──────┬───────────┘
+ │ │
+ │ ├──► YT-A (40%)
+ │ ├──► YT-B (30%)
+ │ ├──► YT-C (20%)
+ │ └──► WUSD (10%)
+ ▼
+┌───────────────┐
+│ ytLP Token │
+│ (ERC20) │
+│ 持有即增值 │
+└───────────────┘
+
+辅助合约:
+├─ USDY.sol (统一计价代币)
+└─ YTPriceFeed.sol (价格读取器)
+流程图查看网站:https://www.processon.com/mermaid
+2.1 系统总览架构图
+Plain Text
+graph TB
+ subgraph "用户交互层"
+ User[用户]
+ Router[YTRewardRouter
一站式入口]
+ end
+
+ subgraph "核心业务层"
+ PoolManager[YTPoolManager
流动性管理]
+ Vault[YTVault
资金池 + 动态手续费]
+ USDY[USDY Token
统一计价单位]
+ end
+
+ subgraph "资产层"
+ YTA[YT-A Token
40% 目标占比]
+ YTB[YT-B Token
30% 目标占比]
+ YTC[YT-C Token
20% 目标占比]
+ WUSD[WUSD Token
10% 目标占比
0x7Cd017...c41]
+ end
+
+ subgraph "LP代币层"
+ YTLP[ytLP Token
流动性凭证]
+ end
+
+ subgraph "奖励层"
+ FeeTracker[FeeYtLPTracker
手续费奖励追踪]
+ end
+
+ User -->|存入/取出/交换| Router
+ Router -->|管理流动性| PoolManager
+ Router -->|质押ytLP| FeeTracker
+ PoolManager -->|buyUSDY/sellUSDY| Vault
+ PoolManager <-->|铸造/销毁| YTLP
+ PoolManager <-->|转移USDY| USDY
+
+ Vault -->|持有| YTA
+ Vault -->|持有| YTB
+ Vault -->|持有| YTC
+ Vault -->|持有| WUSD
+ Vault <-->|铸造/销毁| USDY
+
+ FeeTracker -->|分发奖励| USDY
+
+ style WUSD fill:#90EE90
+ style USDY fill:#FFD700
+ style Vault fill:#87CEEB
+2.2 用户存入流程图
+Plain Text
+flowchart LR
+ subgraph "输入"
+ A[用户YT代币
10,000 YT-A]
+ end
+
+ subgraph "Router处理"
+ B[收集用户代币]
+ end
+
+ subgraph "PoolManager处理"
+ C[调用Vault.buyUSDY]
+ D[计算ytLP数量
ytLP = USDY * supply / AUM]
+ E[铸造ytLP]
+ end
+
+ subgraph "Vault处理"
+ F[接收YT代币
poolAmounts增加]
+ G[计算手续费
0.3% = 30 YT-A]
+ H[更新USDY债务
usdyAmounts增加]
+ I[铸造USDY
9,970 USDY]
+ end
+
+ subgraph "输出"
+ J[用户获得ytLP
价值9,970 USDY]
+ end
+
+ A --> B
+ B --> C
+ C --> F
+ F --> G
+ G --> H
+ H --> I
+ I --> D
+ D --> E
+ E --> J
+
+ style A fill:#90EE90
+ style J fill:#FFD700
+ style G fill:#FFA07A
+2.3 用户取出流程图
+Plain Text
+flowchart LR
+ subgraph "输入"
+ A[用户ytLP
5,000 ytLP]
+ end
+
+ subgraph "PoolManager处理"
+ B[销毁ytLP]
+ C[计算USDY价值
USDY = ytLP * AUM / supply]
+ D[转USDY给Vault
5,000 USDY]
+ end
+
+ subgraph "Vault处理"
+ E[收到USDY并销毁]
+ F[计算YT数量
根据价格]
+ G[计算手续费
动态费率]
+ H[减少poolAmounts
减少usdyAmounts]
+ I[转YT代币]
+ end
+
+ subgraph "输出"
+ J[用户收到YT
4,985 YT-A]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+ D --> E
+ E --> F
+ F --> G
+ G --> H
+ H --> I
+ I --> J
+
+ style A fill:#FFD700
+ style J fill:#90EE90
+ style G fill:#FFA07A
+2.4 YT代币互换流程图
+Plain Text
+flowchart LR
+ subgraph "输入"
+ A[用户YT-A
1,000 YT-A]
+ end
+
+ subgraph "Vault处理"
+ B[收到YT-A
poolAmounts增加]
+ C[查询价格
priceA, priceB]
+ D[计算USDY中间值
1,000 * priceA]
+ E[计算YT-B数量
USDY / priceB]
+ F[计算动态手续费
检查两端占比]
+ G[更新状态
YT-A增, YT-B减
USDY债务转移]
+ H[转出YT-B]
+ end
+
+ subgraph "输出"
+ I[用户收到YT-B
997 YT-B]
+ end
+
+ A --> B
+ B --> C
+ C --> D
+ D --> E
+ E --> F
+ F --> G
+ G --> H
+ H --> I
+
+ style A fill:#90EE90
+ style I fill:#87CEEB
+ style F fill:#FFA07A
+2.5 USDY铸造销毁流程图
+Plain Text
+graph TB
+ subgraph "USDY生命周期"
+ Create[创建: 用户存入YT]
+ Mint[Vault铸造USDY]
+ Hold[PoolManager持有USDY]
+ Transfer[PoolManager转USDY给Vault]
+ Burn[Vault销毁USDY]
+ Destroy[结束: 用户取回YT]
+ end
+
+ subgraph "关键状态"
+ Supply[USDY总供应量]
+ PoolBalance[PoolManager余额]
+ Debt[各代币USDY债务]
+ end
+
+ Create --> Mint
+ Mint --> Supply
+ Mint --> Hold
+ Hold --> PoolBalance
+ Hold --> Transfer
+ Transfer --> Burn
+ Burn --> Supply
+ Burn --> Destroy
+
+ Mint -.更新.-> Debt
+ Burn -.更新.-> Debt
+
+ style Mint fill:#90EE90
+ style Burn fill:#FFB6C1
+ style Supply fill:#FFD700
+2.6 动态手续费架构图
+Plain Text
+graph TB
+ subgraph "输入层"
+ User[用户操作
存入/取出/Swap]
+ Token[操作的代币
YT-A/YT-B/YT-C/WUSD]
+ Amount[操作数量]
+ end
+
+ subgraph "状态查询层"
+ Current[当前USDY债务
usdyAmounts]
+ Target[目标USDY债务
getTargetUsdyAmount]
+ Weight[代币权重
tokenWeights]
+ Supply[USDY总供应
totalSupply]
+ end
+
+ subgraph "计算层"
+ Calc1[计算操作后债务
nextAmount]
+ Calc2[计算偏离度
initialDiff vs nextDiff]
+ Calc3[判断改善/恶化]
+ end
+
+ subgraph "手续费决策层"
+ Decision{改善平衡?}
+ Rebate[降低手续费
baseFee - rebate]
+ Penalty[提高手续费
baseFee + tax]
+ end
+
+ subgraph "输出层"
+ Final[最终手续费
0% - 0.8%]
+ Effect[效果反馈
引导池子平衡]
+ end
+
+ User --> Token
+ Token --> Amount
+ Amount --> Current
+
+ Current --> Calc1
+ Target --> Calc1
+ Weight --> Target
+ Supply --> Target
+
+ Calc1 --> Calc2
+ Calc2 --> Calc3
+ Calc3 --> Decision
+
+ Decision -->|是| Rebate
+ Decision -->|否| Penalty
+
+ Rebate --> Final
+ Penalty --> Final
+ Final --> Effect
+
+ style Decision fill:#FFD700
+ style Rebate fill:#90EE90
+ style Penalty fill:#FFA07A
+ style Final fill:#87CEEB
+2.7 各YT代币价格获取图
+Plain Text
+graph TB
+ subgraph "价格查询层"
+ Query[Vault查询价格
getPrice]
+ end
+
+ subgraph "YTPriceFeed"
+ Feed[价格读取器]
+ Check{是WUSD?}
+ end
+
+ subgraph "WUSD处理"
+ Fixed[返回固定价格
1.0 USDY]
+ end
+
+ subgraph "YT代币处理"
+ YTContract[YT代币合约]
+ ReadVar[ 直接读取public变量
assetPrice]
+ AddSpread[添加价差
0.2%]
+ end
+
+ subgraph "返回"
+ Price[返回USDY价格
30位小数]
+ end
+
+ Query --> Feed
+ Feed --> Check
+
+ Check -->|是| Fixed
+ Check -->|否| YTContract
+
+ YTContract --> ReadVar
+ Note1[:只读一个变量
Gas成本极低]
+ ReadVar -.说明.-> Note1
+ ReadVar --> AddSpread
+
+ AddSpread --> Price
+ Fixed --> Price
+
+ style Check fill:#FFD700
+ style Fixed fill:#90EE90
+ style ReadVar fill:#87CEEB
+ style Note1 fill:#FFE4B5
+3. 收益机制设计
+3.1 自动复利机制
+Plain Text
+ytLP自动增值模型
+
+┌──────────────────────┐
+│ 用户持有 ytLP │
+│ (无需质押,无需领取) │
+└────────┬─────────────┘
+ │
+ ▼
+┌──────────────────────┐
+│ 池子收取手续费 │
+│ ├─ Swap手续费 │
+│ ├─ 存取手续费 │
+│ └─ 全部留在池子中 │
+└────────┬─────────────┘
+ │
+ ▼
+┌──────────────────────┐
+│ 池子总价值(AUM)自动增长 │
+│ AUM = Σ(poolAmounts * prices) │
+│ 手续费 → poolAmounts ↑ │
+└────────┬─────────────┘
+ │
+ ▼
+┌──────────────────────┐
+│ ytLP价格自动上涨 │
+│ ytLP价格 = AUM / ytLP总量 │
+│ 持有者自动获得收益 │
+└──────────────────────┘
+3.2 收益来源
+Plain Text
+| 收益来源 | 实现方式 | 说明 |
+|---------|---------|------|
+| **YT Swap手续费** | 留在池子 | 手续费不转出,直接增加poolAmounts |
+| **存入手续费** | 留在池子 | 用户存入时收取的手续费留在池子 |
+| **取出手续费** | 留在池子 | 用户取出时收取的手续费留在池子 |
+| **YT 增值** | 自动 | YT代币本身增值,体现在价格 |
+优势:
+• ✅ 100%手续费归LP
+• ✅ 自动复利,无需操作
+• ✅ Gas高效,零额外成本
+3.3 自动复利效果演示
+Plain Text
+场景:Alice持有1000 ytLP
+
+T0: 初始状态
+├─ 池子AUM: 100M USDY
+├─ ytLP总量: 100M
+├─ ytLP价格: 1.0 USDY
+├─ Alice持有: 1000 ytLP
+└─ Alice价值: 1000 USDY
+
+T1: 1天后(产生手续费)
+├─ 每日交易量: 5M USDY
+├─ 平均手续费: 0.3%
+├─ 日手续费: 15,000 USDY
+├─ 手续费留在池子 ✅
+│
+├─ 池子AUM: 100,015,000 USDY
+├─ ytLP总量: 100M (不变)
+├─ ytLP价格: 1.00015 USDY ⬆️
+├─ Alice持有: 1000 ytLP (不变)
+└─ Alice价值: 1000.15 USDY ✅ (+0.015%)
+
+T30: 30天后(复利累积)
+├─ 累积手续费: ~450,000 USDY
+├─ 池子AUM: 100,450,000 USDY
+├─ ytLP价格: 1.0045 USDY ⬆️
+├─ Alice持有: 1000 ytLP
+└─ Alice价值: 1004.5 USDY ✅ (+0.45%)
+
+T365: 1年后(年化收益)
+├─ 累积手续费: ~5.475M USDY
+├─ 加上YT增值: ~8M USDY
+├─ 池子AUM: 113.475M USDY
+├─ ytLP价格: 1.13475 USDY ⬆️
+├─ Alice持有: 1000 ytLP
+└─ Alice价值: 1134.75 USDY ✅ (+13.475%)
+
+Alice全程无需任何操作!
+只需持有ytLP,价值自动增长
+4. 动态手续费
+4.1 动态手续费机制
+场景1:YT-A占比过高
+公式:
+avg_dev = (|D_after| + |D_before|)/2
+adjustment = K * avg_dev / target
+Plain Text
+当前状态:
+YT-A: usdyAmounts = 50M, 目标 = 40M (+10M, 占比过高)
+YT-B: usdyAmounts = 30M, 目标 = 30M (正好)
+YT-C: usdyAmounts = 15M, 目标 = 20M (-5M, 占比过低)
+WUSD: usdyAmounts = 5M, 目标 = 10M (-5M, 占比过低)
+
+用户A想存入1M USDY价值的YT-A:
+┌─────────────────────────────────────┐
+│ 初始偏离: +10M │
+│ 操作后偏离: +11M (恶化平衡) │
+│ 基础手续费: 0.3% (30 bps) │
+│ 税费计算: 50 * 10.5M / 40M ≈ 13 bps │
+│ 最终手续费: 30 + 13 = 43 bps (0.43%) │
+└─────────────────────────────────────┘
+结果:手续费提高 43% → 😱 惩罚
+
+用户B想存入1M USDY价值的YT-C:
+┌─────────────────────────────────────┐
+│ 初始偏离: -5M │
+│ 操作后偏离: -4M (改善平衡) │
+│ 基础手续费: 0.3% (30 bps) │
+│ 折扣计算: 50 * 5M / 20M = 12.5 bps │
+│ 最终手续费: 30 - 12.5 = 17.5 bps │
+└─────────────────────────────────────┘
+结果:手续费降低 42% → 🎉 激励
+
+用户C想从YT-A换到YT-C:
+┌─────────────────────────────────────┐
+│ YT-A减少 → 改善平衡 ✅ │
+│ YT-C增加 → 改善平衡 ✅ │
+│ 最终手续费: 可能接近0% 🎁 │
+└─────────────────────────────────────┘
+结果:双重鼓励!
+场景2:WUSD作为稳定资产
+Plain Text
+WUSD (0x7Cd017ca5ddb86861FA983a34b5F495C6F898c41)
+
+特点:
+✅ 稳定币,价格 ≈ $1
+✅ 可以直接存入池子
+✅ 目标占比: 50%
+✅ 作为池子的"稳定锚"
+
+动态手续费:
+当WUSD占比过低时 → 鼓励存入WUSD
+当WUSD占比过高时 → 鼓励取出WUSD
+
+用户存入WUSD场景:
+当前: WUSD占5M,目标10M
+存入5M WUSD:
+- 改善平衡 → 手续费可能只有0.05% 🎉
+4.2 手续费范围
+Plain Text
+YT代币互换:
+- 最低: 0% (大幅改善平衡)
+- 正常: 0.3% (平衡状态)
+- 最高: 0.8% (严重失衡)
+
+涉及WUSD的操作:
+- 最低: 0% (大幅改善平衡)
+- 正常: 0.04% (平衡状态)
+- 最高: 0.24% (严重失衡)
+4.3 USDY债务追踪机制
+Solidity
+// usdyAmounts: 追踪每个代币的USDY债务
+mapping(address => uint256) public usdyAmounts;
+
+// 存入YT-A时:
+buyUSDY(YT-A) {
+ // 1. 收YT-A
+ // 2. 增加池子中YT-A数量
+ // 3. 增加usdyAmounts[YT-A] ← 关键!
+ // 4. 铸造USDY给用户
+}
+
+// 取出YT-B时:
+sellUSDY(YT-B) {
+ // 1. 收用户的USDY并销毁
+ // 2. 减少usdyAmounts[YT-B] ← 关键!
+ // 3. 减少池子中YT-B数量
+ // 4. 转YT-B给用户
+}
+
+// Swap: YT-A → YT-C时:
+swap(YT-A, YT-C) {
+ // 1. 收YT-A,增加usdyAmounts[YT-A]
+ // 2. 转YT-C,减少usdyAmounts[YT-C]
+ // 3. 根据两边的偏离度计算手续费
+}
+4.4 USDY主要作用
+✅ 统一计价:所有YT转换为USDY价值
+✅ 价值传递:PoolManager和Vault通过USDY交互
+✅ 动态手续费:usdyAmounts追踪债务,自动平衡
+✅ 按需铸造:资金高效利用,会计清晰
+4.4.1 举例说明
+Plain Text
+场景:你去商店用积分换商品
+├─ 你:有1000积分(ytLP)
+├─ 积分中心(PoolManager):销毁你的积分
+├─ 商店(Vault):有商品(YT代币)
+└─ 问题:商店凭什么给你商品?
+
+解决方案:
+1. 积分中心销毁你的积分 ✅
+2. 积分中心给商店"提货券"(USDY) ✅ ← 关键!
+3. 商店验证提货券 ✅
+4. 商店给你商品 ✅
+5. 商店销毁提货券 ✅
+
+如果没有第2步(转USDY):
+├─ 商店不知道你有权拿商品
+├─ 商店无法验证价值
+└─ ❌ 系统无法运转
+
diff --git a/document/ytLp流动性池系统操作流程文档.md b/document/ytLp流动性池系统操作流程文档.md
new file mode 100644
index 0000000..f464dab
--- /dev/null
+++ b/document/ytLp流动性池系统操作流程文档.md
@@ -0,0 +1,681 @@
+ytLp流动性池系统操作流程文档
+目录
+1. [添加流动性流程](#1-添加流动性流程)
+2. [移除流动性流程](#2-移除流动性流程)
+3. [代币互换流程](#3-代币互换流程)
+4. [添加白名单代币流程](#4-添加白名单代币流程)
+5. [移除白名单代币流程](#5-移除白名单代币流程)
+
+1. 添加流动性流程
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户 (User) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 1. 调用 addLiquidity(token, amount, minUsdy, minYtLP)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTRewardRouter.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function addLiquidity( │
+│ address _token, // YT-A 代币地址 │
+│ uint256 _amount, // 1000 个代币 │
+│ uint256 _minUsdy, // 最小997 USDY(滑点保护) │
+│ uint256 _minYtLP // 最小995 ytLP(滑点保护) │
+│ ) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 2. transferFrom(user → YTRewardRouter)
+ │ 转移1000个YT-A到Router
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 代币转移检查 │
+│ ✓ 检查用户授权额度 │
+│ ✓ 转移代币到Router │
+│ ✓ approve(YTPoolManager, amount) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 3. 调用 addLiquidityForAccount()
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTPoolManager.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function addLiquidityForAccount( │
+│ address _fundingAccount, // YTRewardRouter │
+│ address _account, // 用户地址 │
+│ address _token, // YT-A │
+│ uint256 _amount, // 1000 │
+│ uint256 _minUsdy, // 997 │
+│ uint256 _minYtLP // 995 │
+│ ) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 4. 计算当前AUM(使用MaxPrice)
+ │ getAumInUsdy(true)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ AUM 计算(对用户保守) │
+│ ┌───────────────────────────────────────────────────────┐ │
+│ │ YTVault.getPoolValue(true) │ │
+│ │ • 获取池中所有YT代币数量 │ │
+│ │ • 使用 MaxPrice(上浮价差)计算每个代币价值 │ │
+│ │ • 汇总得到 AUM = $100,200 │ │
+│ └───────────────────────────────────────────────────────┘ │
+│ 当前ytLP供应量: 100,000 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 5. 调用 buyUSDY()
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTVault.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function buyUSDY(address _token, address _receiver) │
+│ │
+│ 步骤: │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ ① transferIn(_token) │ │
+│ │ • 接收1000个YT-A │ │
+│ │ │ │
+│ │ ② 获取价格(使用MinPrice,低估用户资产) │ │
+│ │ price = _getPrice(_token, false) │ │
+│ │ • 基础价格: $1.00 │ │
+│ │ • MinPrice: $0.998 (下压0.2%价差) │ │
+│ │ │ │
+│ │ ③ 计算理论USDY价值 │ │
+│ │ usdyAmount = 1000 × $0.998 = $998 │ │
+│ │ │ │
+│ │ ④ 获取手续费率(动态) │ │
+│ │ feeBps = getSwapFeeBasisPoints(_token, usdy, 998) │ │
+│ │ • 检查是否稳定币互换 │ │
+│ │ • YT代币: 30 bps (0.3%) │ │
+│ │ • 稳定币: 4 bps (0.04%) │ │
+│ │ • 根据池子平衡动态调整 │ │
+│ │ → 本次: 30 bps │ │
+│ │ │ │
+│ │ ⑤ 计算扣费后的USDY │ │
+│ │ feeAmount = 1000 × 0.3% = 3个代币 │ │
+│ │ amountAfterFees = 997个代币 │ │
+│ │ usdyAmountAfterFees = 997 × $0.998 = $995.006 │ │
+│ │ │ │
+│ │ ⑥ 池子记账 │ │
+│ │ _increasePoolAmount(_token, 1000) // 全部代币入池 │ │
+│ │ _increaseUsdyAmount(_token, 995) // 只记扣费后的债务 │ │
+│ │ │ │
+│ │ ⑦ 铸造USDY │ │
+│ │ USDY.mint(_receiver, 995) │ │
+│ │ • 手续费3个代币留在池中 │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+│ │
+│ 返回: 995 USDY │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 6. 检查 USDY 数量
+ │ require(995 >= 997) ❌ 会失败
+ │ (实际应该传入更小的 minUsdy)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 回到 YTPoolManager - 铸造 ytLP │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ 计算铸造数量: │ │
+│ │ ytLPSupply = 100,000 │ │
+│ │ aumInUsdy = $100,200 │ │
+│ │ usdyAmount = $995 │ │
+│ │ │ │
+│ │ mintAmount = 995 × 100,000 / 100,200 = 993.03 ytLP │ │
+│ │ │ │
+│ │ 检查滑点保护: │ │
+│ │ require(993.03 >= 995) ❌ 会失败 │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+│ │
+│ 执行铸造: │
+│ YTLPToken.mint(user, 993.03) │
+│ lastAddedAt[user] = block.timestamp // 记录时间(冷却期) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 7. 返回结果
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户收到 │
+│ ✓ 993.03 ytLP │
+│ ✓ 代表在池中的份额 │
+│ │
+│ 成本分析: │
+│ 存入: 1000 YT-A │
+│ 手续费: 3 YT-A (0.3%) │
+│ 价差损失: ~4 YT-A (0.4%) │
+│ 总成本: ~0.7% │
+└─────────────────────────────────────────────────────────────────────┘
+涉及的合约函数:
+合约 函数 作用
+YTRewardRouter addLiquidity() 用户入口,处理代币转移
+YTPoolManager addLiquidityForAccount() 流动性管理,计算ytLP
+YTPoolManager getAumInUsdy(true) 获取AUM(使用MaxPrice)
+YTVault buyUSDY() 接收代币,铸造USDY
+YTVault getPoolValue(true) 计算池子总价值
+YTVault getSwapFeeBasisPoints() 获取动态手续费率
+YTPriceFeed getPrice(_token, false) 获取MinPrice
+USDY mint() 铸造USDY代币
+YTLPToken mint() 铸造ytLP代币
+
+2. 移除流动性流程
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户 (User) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 1. 调用 removeLiquidity(tokenOut, ytLPAmount, minOut, receiver)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTRewardRouter.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function removeLiquidity( │
+│ address _tokenOut, // YT-B 代币地址 │
+│ uint256 _ytLPAmount, // 1000 ytLP │
+│ uint256 _minOut, // 最小990 YT-B(滑点保护) │
+│ address _receiver // 接收地址 │
+│ ) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 2. 调用 removeLiquidityForAccount()
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTPoolManager.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function removeLiquidityForAccount(...) │
+│ │
+│ 步骤: │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ ① 检查冷却期 │ │
+│ │ require(lastAddedAt[user] + 15分钟 <= now) │ │
+│ │ │ │
+│ │ ② 计算AUM(使用MinPrice,对用户保守) │ │
+│ │ aumInUsdy = getAumInUsdy(false) │ │
+│ │ • YTVault.getPoolValue(false) │ │
+│ │ • 使用MinPrice(下压价差) │ │
+│ │ • AUM = $99,800 │ │
+│ │ │ │
+│ │ ③ 计算USDY价值 │ │
+│ │ ytLPSupply = 100,000 │ │
+│ │ usdyAmount = 1000 × 99,800 / 100,000 = $998 │ │
+│ │ │ │
+│ │ ④ 检查并铸造USDY(如果余额不足) │ │
+│ │ balance = USDY.balanceOf(PoolManager) │ │
+│ │ if (998 > balance) { │ │
+│ │ USDY.mint(PoolManager, 998 - balance) │ │
+│ │ } │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 3. 销毁ytLP
+ │ YTLPToken.burn(user, 1000)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ ytLP 销毁完成 │
+│ 用户的ytLP余额 -1000 │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 4. 调用 sellUSDY()
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTVault.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function sellUSDY(address _token, address _receiver) │
+│ │
+│ 步骤: │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ ① transferIn(usdy) │ │
+│ │ • 接收998 USDY │ │
+│ │ │ │
+│ │ ② 获取价格(使用MaxPrice,高估需支付的价值) │ │
+│ │ price = _getPrice(_token, true) │ │
+│ │ • 基础价格: $1.00 │ │
+│ │ • MaxPrice: $1.002 (上浮0.2%价差) │ │
+│ │ │ │
+│ │ ③ 计算理论赎回数量 │ │
+│ │ redemptionAmount = 998 / 1.002 = 996.01 YT-B │ │
+│ │ │ │
+│ │ ④ 获取赎回手续费率 │ │
+│ │ feeBps = getRedemptionFeeBasisPoints(_token, 998) │ │
+│ │ • USDY已被标记为稳定币 │ │
+│ │ • 如果_token也是稳定币: 4 bps │ │
+│ │ • 如果_token是YT代币: 30 bps │ │
+│ │ → 本次(YT-B): 30 bps │ │
+│ │ │ │
+│ │ ⑤ 计算扣费后的输出 │ │
+│ │ amountOut = 996.01 × (1 - 0.3%) │ │
+│ │ = 993.02 YT-B │ │
+│ │ │ │
+│ │ ⑥ 池子记账 │ │
+│ │ _decreasePoolAmount(_token, 993.02) // 减少池中代币 │ │
+│ │ _decreaseUsdyAmount(_token, ...) // 减少债务 │ │
+│ │ │ │
+│ │ ⑦ 销毁USDY │ │
+│ │ USDY.burn(address(this), 998) │ │
+│ │ │ │
+│ │ ⑧ 转出代币 │ │
+│ │ transfer(_receiver, 993.02 YT-B) │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+│ │
+│ 返回: 993.02 YT-B │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 5. 检查滑点保护
+ │ require(993.02 >= 990) ✓
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户收到 │
+│ ✓ 993.02 YT-B │
+│ │
+│ 成本分析: │
+│ 赎回: 1000 ytLP │
+│ 手续费: ~3 YT-B (0.3%) │
+│ 价差损失: ~4 YT-B (0.4%) │
+│ 总成本: ~0.7% │
+└─────────────────────────────────────────────────────────────────────┘
+涉及的合约函数:
+合约 函数 作用
+YTRewardRouter removeLiquidity() 用户入口
+YTPoolManager removeLiquidityForAccount() 计算USDY价值
+YTPoolManager getAumInUsdy(false) 获取AUM(使用MinPrice)
+YTVault sellUSDY() 用USDY换回代币
+YTVault getRedemptionFeeBasisPoints() 获取赎回手续费率
+YTPriceFeed getPrice(_token, true) 获取MaxPrice
+USDY mint() 补充USDY(如需要)
+USDY burn() 销毁USDY
+YTLPToken burn() 销毁ytLP
+
+3. 代币互换流程
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户 (User) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 1. 调用 swapYT(tokenIn, tokenOut, amountIn, minOut, receiver)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTRewardRouter.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function swapYT( │
+│ address _tokenIn, // YT-A │
+│ address _tokenOut, // YT-B │
+│ uint256 _amountIn, // 1000 │
+│ uint256 _minOut, // 990(滑点保护) │
+│ address _receiver // 接收地址 │
+│ ) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 2. transferFrom(user → YTVault)
+ │ 转移1000个YT-A直接到Vault
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTVault.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function swap( │
+│ address _tokenIn, // YT-A │
+│ address _tokenOut, // YT-B │
+│ address _receiver // 用户 │
+│ ) │
+│ │
+│ 步骤: │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ ① 安全检查 │ │
+│ │ ✓ swap已启用 │ │
+│ │ ✓ tokenIn已白名单 │ │
+│ │ ✓ tokenOut已白名单 │ │
+│ │ ✓ tokenIn != tokenOut │ │
+│ │ │ │
+│ │ ② transferIn(_tokenIn) │ │
+│ │ • 检测转入的YT-A数量: 1000 │ │
+│ │ │ │
+│ │ ③ 检查单笔交易限额 │ │
+│ │ if (maxSwapAmount[tokenIn] > 0) { │ │
+│ │ require(1000 <= maxSwapAmount[tokenIn]) │ │
+│ │ } │ │
+│ │ │ │
+│ │ ④ 获取价格(对协议有利的定价) │ │
+│ │ priceIn = _getPrice(_tokenIn, false) // MinPrice │ │
+│ │ = $0.998 (低估输入) │ │
+│ │ priceOut = _getPrice(_tokenOut, true) // MaxPrice │ │
+│ │ = $1.002 (高估输出) │ │
+│ │ │ │
+│ │ ⑤ 计算中间USDY价值 │ │
+│ │ usdyAmount = 1000 × $0.998 / 1e30 = $998 │ │
+│ │ │ │
+│ │ ⑥ 检查每日交易量限制 │ │
+│ │ _checkDailySwapLimit(998) │ │
+│ │ │ │
+│ │ ⑦ 计算理论输出(扣费前) │ │
+│ │ amountOut = 998 × 1e30 / $1.002 │ │
+│ │ = 996.01 YT-B │ │
+│ │ │ │
+│ │ ⑧ 获取swap手续费率(动态) │ │
+│ │ feeBps = getSwapFeeBasisPoints(tokenIn, tokenOut, 998) │ │
+│ │ │ │
+│ │ 判断逻辑: │ │
+│ │ • 是否稳定币互换? │ │
+│ │ isStableSwap = stableTokens[YT-A] && stableTokens[YT-B] │ │
+│ │ = false && false = false │ │
+│ │ │ │
+│ │ • 基础费率: 30 bps (非稳定币) │ │
+│ │ • 税率: 50 bps │ │
+│ │ │ │
+│ │ • 动态调整(改善平衡 → 降低费率): │ │
+│ │ ├─ YT-A: 当前50k, 目标40k → 过多 → 增加费率 │ │
+│ │ └─ YT-B: 当前30k, 目标40k → 不足 → 减少费率 │ │
+│ │ │ │
+│ │ • 计算两个代币的费率,取较高者 │ │
+│ │ fee_A = getFeeBasisPoints(YT-A, 998, 30, 50, true) │ │
+│ │ = 40 bps (恶化平衡,提高) │ │
+│ │ fee_B = getFeeBasisPoints(YT-B, 998, 30, 50, false) │ │
+│ │ = 20 bps (改善平衡,降低) │ │
+│ │ │ │
+│ │ → 最终费率: max(40, 20) = 40 bps (0.4%) │ │
+│ │ │ │
+│ │ ⑨ 扣除手续费 │ │
+│ │ amountOutAfterFees = 996.01 × (1 - 0.4%) │ │
+│ │ = 992.02 YT-B │ │
+│ │ │ │
+│ │ ⑩ 全局滑点保护 │ │
+│ │ _validateSwapSlippage(1000, 992.02, priceIn, priceOut) │ │
+│ │ │ │
+│ │ ⑪ 更新池子状态 │ │
+│ │ _increasePoolAmount(YT-A, 1000) // YT-A入池 │ │
+│ │ _decreasePoolAmount(YT-B, 992.02) // YT-B出池 │ │
+│ │ _increaseUsdyAmount(YT-A, 998) // YT-A债务+998 │ │
+│ │ _decreaseUsdyAmount(YT-B, 998) // YT-B债务-998 │ │
+│ │ │ │
+│ │ ⑫ 转出代币 │ │
+│ │ transfer(_receiver, 992.02 YT-B) │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+│ │
+│ 返回: 992.02 YT-B │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 3. 检查滑点保护
+ │ require(992.02 >= 990) ✓
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 用户收到 │
+│ ✓ 992.02 YT-B │
+│ │
+│ 成本分析: │
+│ 输入: 1000 YT-A │
+│ 价差损失: ~4 YT (0.4%) │
+│ 手续费: ~4 YT (0.4% 动态) │
+│ 输出: 992.02 YT-B │
+│ 总成本: ~0.8% │
+│ │
+│ 有效汇率: 1 YT-A = 0.9920 YT-B │
+└─────────────────────────────────────────────────────────────────────┘
+涉及的合约函数:
+合约 函数 作用
+YTRewardRouter swapYT() 用户入口,转移代币
+YTVault swap() 执行代币互换
+YTVault getSwapFeeBasisPoints() 获取动态swap费率
+YTVault getFeeBasisPoints() 计算单个代币的动态费率
+YTVault _validateSwapSlippage() 全局滑点保护
+YTVault _checkDailySwapLimit() 检查每日限额
+YTPriceFeed getMinPrice() 输入代币价格
+YTPriceFeed getMaxPrice() 输出代币价格
+
+4. 添加白名单代币流程
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 管理员 (Gov) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 1. 调用 setWhitelistedToken(...)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTVault.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function setWhitelistedToken( │
+│ address _token, // 新YT代币地址 │
+│ uint256 _decimals, // 18 │
+│ uint256 _weight, // 权重 10000 (10%) │
+│ uint256 _maxUsdyAmount, // 最大USDY债务 1000000e18 │
+│ bool _isStable // false (YT代币非稳定币) │
+│ ) │
+│ │
+│ 步骤: │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ ① 安全检查 │ │
+│ │ require(_token != address(0)) │ │
+│ │ require(msg.sender == gov) // 只有管理员 │ │
+│ │ │ │
+│ │ ② 检查是否已在白名单 │ │
+│ │ if (!whitelistedTokens[_token]) { │ │
+│ │ allWhitelistedTokens.push(_token) // 添加到数组 │ │
+│ │ whitelistedTokens[_token] = true // 标记为白名单 │ │
+│ │ } │ │
+│ │ │ │
+│ │ ③ 更新总权重 │ │
+│ │ oldWeight = tokenWeights[_token] // 0(新代币) │ │
+│ │ totalTokenWeights = totalTokenWeights - oldWeight + 10000 │ │
+│ │ │ │
+│ │ 示例(自动比例调整): │ │
+│ │ ┌──────────────┬────────┬──────────┬──────────┐ │ │
+│ │ │ 代币 │ 权重 │ 旧占比 │ 新占比 │ │ │
+│ │ ├──────────────┼────────┼──────────┼──────────┤ │ │
+│ │ │ YT-A (原有) │ 30000 │ 30.0% │ 27.27% │ ← 自动变化│ │
+│ │ │ YT-B (原有) │ 30000 │ 30.0% │ 27.27% │ │ │
+│ │ │ YT-C (原有) │ 30000 │ 30.0% │ 27.27% │ │ │
+│ │ │ WUSD (原有) │ 10000 │ 10.0% │ 9.09% │ │ │
+│ │ │ YT-D (新增) │ 10000 │ - │ 9.09% │ ← 新增 │ │
+│ │ ├──────────────┼────────┼──────────┼──────────┤ │ │
+│ │ │ 总计 │ 110000 │ 100% │ 100% │ │ │
+│ │ └──────────────┴────────┴──────────┴──────────┘ │ │
+│ │ │ │
+│ │ ⚠️ 重要:使用相对权重,不需要保持总和为100000 │ │
+│ │ totalTokenWeights可以是任意值,关键是相对比例 │ │
+│ │ │ │
+│ │ ④ 设置代币参数 │ │
+│ │ tokenDecimals[_token] = 18 │ │
+│ │ tokenWeights[_token] = 10000 │ │
+│ │ maxUsdyAmounts[_token] = 1000000e18 // 最大100万USDY债务 │ │
+│ │ stableTokens[_token] = false // 标记非稳定币 │ │
+│ │ │ │
+│ │ ⑤ 白名单添加完成 │ │
+│ │ ✓ 代币可以被存入 │ │
+│ │ ✓ 代币可以被swap │ │
+│ │ ✓ 代币开始计入AUM │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 2. 需要配置价格预言机
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTPriceFeed.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ 需要执行的配置: │
+│ │
+│ ① 设置价差 (可选但推荐) │
+│ setSpreadBasisPoints(YT-D, 20) // 0.2% 价差 │
+│ │
+│ ② 初始化价格 (如果需要) │
+│ forceUpdatePrice(YT-D, 1e30) // 初始价格 $1.00 │
+│ │
+│ 注意: YT代币需要实现 assetPrice() 接口 │
+│ 价格预言机会自动读取该接口获取价格 │
+└─────────────────────────────────────────────────────────────────────┘
+ │
+ │ 3. 配置完成
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 白名单生效 │
+│ │
+│ 用户可以: │
+│ ✓ 用YT-D添加流动性 │
+│ ✓ 用ytLP换回YT-D │
+│ ✓ YT-D与其他YT代币互换 │
+│ │
+│ 协议会: │
+│ ✓ 将YT-D计入AUM(按10%权重) │
+│ ✓ 对YT-D使用0.3%的swap费率(非稳定币) │
+│ ✓ 动态调整费率以维持池子平衡 │
+└─────────────────────────────────────────────────────────────────────┘
+涉及的合约函数:
+合约 函数 作用
+YTVault setWhitelistedToken() 添加代币到白名单
+YTPriceFeed setSpreadBasisPoints() 设置代币价差
+YTPriceFeed forceUpdatePrice() 初始化价格(可选)
+白名单代币要求:
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ YT代币必须实现的接口 │
+│ │
+│ interface IYTToken { │
+│ // 必需:返回当前资产价格(30位精度) │
+│ function assetPrice() external view returns (uint256); │
+│ │
+│ // ERC20标准接口 │
+│ function decimals() external view returns (uint8); │
+│ function balanceOf(address) external view returns (uint256); │
+│ function transfer(address, uint256) external returns (bool); │
+│ function transferFrom(address, address, uint256) │
+│ external returns (bool); │
+│ } │
+│ │
+│ 价格示例: │
+│ $1.00 = 1 × 10^30 = 1000000000000000000000000000000 │
+│ $0.998 = 998000000000000000000000000000 │
+└─────────────────────────────────────────────────────────────────────┘
+
+5. 移除白名单代币流程
+Plain Text
+┌─────────────────────────────────────────────────────────────────────┐
+│ 管理员 (Gov) │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 1. 先确保池中该代币已清空
+ │ (用户需先移除流动性)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 检查代币状态 │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ 检查池子余额: │ │
+│ │ poolAmounts[YT-D] = ? │ │
+│ │ usdyAmounts[YT-D] = ? │ │
+│ │ │ │
+│ │ 安全建议: │ │
+│ │ ✓ 池中余额应为0或接近0 │ │
+│ │ ✓ USDY债务应为0 │ │
+│ │ ✓ 没有待处理的用户流动性 │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 2. 调用 clearWhitelistedToken(token)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ YTVault.sol │
+│ ───────────────────────────────────────────────────────────────── │
+│ function clearWhitelistedToken(address _token) │
+│ │
+│ 步骤: │
+│ ┌─────────────────────────────────────────────────────────────┐ │
+│ │ ① 安全检查 │ │
+│ │ require(whitelistedTokens[_token]) // 必须已在白名单 │ │
+│ │ require(msg.sender == gov) // 只有管理员 │ │
+│ │ │ │
+│ │ ② 更新总权重 │ │
+│ │ oldWeight = tokenWeights[YT-D] = 10000 │ │
+│ │ totalTokenWeights = totalTokenWeights - 10000 │ │
+│ │ │ │
+│ │ 结果: │ │
+│ │ ┌──────────────┬────────┬────────┐ │ │
+│ │ │ 代币 │ 权重 │ 占比 │ │ │
+│ │ ├──────────────┼────────┼────────┤ │ │
+│ │ │ YT-A │ 30000 │ 30% │ │ │
+│ │ │ YT-B │ 30000 │ 30% │ │ │
+│ │ │ YT-C │ 30000 │ 30% │ │ │
+│ │ │ WUSD │ 10000 │ 10% │ │ │
+│ │ │ YT-D (删除) │ 0 │ - │ ← 已移除 │ │
+│ │ ├──────────────┼────────┼────────┤ │ │
+│ │ │ 总计 │ 100000 │ 100% │ │ │
+│ │ └──────────────┴────────┴────────┘ │ │
+│ │ │ │
+│ │ ③ 清除所有配置 │ │
+│ │ delete whitelistedTokens[_token] // 从白名单移除 │ │
+│ │ delete stableTokens[_token] // 清除稳定币标记 │ │
+│ │ delete tokenDecimals[_token] // 清除精度 │ │
+│ │ delete tokenWeights[_token] // 清除权重 │ │
+│ │ delete maxUsdyAmounts[_token] // 清除最大债务限制 │ │
+│ │ │ │
+│ │ ④ 白名单移除完成 │ │
+│ │ ✓ 代币无法被存入 │ │
+│ │ ✓ 代币无法被swap │ │
+│ │ ✓ 代币不再计入AUM │ │
+│ └─────────────────────────────────────────────────────────────┘ │
+└────────────────────────────┬────────────────────────────────────────┘
+ │
+ │ 3. 后续处理(可选)
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 可选的清理操作 │
+│ │
+│ ① 从 allWhitelistedTokens 数组中移除 │
+│ (注意: 合约当前没有自动移除,需要考虑gas成本) │
+│ │
+│ ② 如果池中还有少量余额,可以提取 │
+│ (启用紧急模式后) │
+│ emergencyMode = true │
+│ withdrawToken(YT-D, gov, amount) │
+│ │
+│ ③ 从价格预言机移除配置(可选) │
+│ 不强制,但可以节省存储 │
+└─────────────────────────────────────────────────────────────────────┘
+ │
+ │ 4. 完成
+ ▼
+┌─────────────────────────────────────────────────────────────────────┐
+│ 移除完成 │
+│ │
+│ 用户无法: │
+│ ✗ 用YT-D添加流动性 │
+│ ✗ 用ytLP换回YT-D │
+│ ✗ YT-D与其他YT代币互换 │
+│ │
+│ 协议: │
+│ ✓ YT-D不再计入AUM计算 │
+│ ✓ 权重已重新分配 │
+└─────────────────────────────────────────────────────────────────────┘
+涉及的合约函数:
+合约 函数 作用
+YTVault clearWhitelistedToken() 从白名单移除代币
+YTVault setEmergencyMode() 启用紧急模式(如需提取余额)
+YTVault withdrawToken() 提取剩余代币(紧急模式下)
+移除白名单的注意事项:
+Plain Text
+⚠️ 重要提示:
+
+1. 移除前确保:
+ • 所有用户已移除该代币的流动性
+ • poolAmounts[token] = 0 或接近0
+ • usdyAmounts[token] = 0
+ • 没有pending的交易
+
+2. 移除后影响:
+ • 该代币的所有操作立即失效
+ • 如果用户还持有该代币的ytLP,无法再换回该代币
+ • 需要重新调整其他代币的权重以维持池子平衡
+
+3. 不可逆操作:
+ • 移除后该代币在 allWhitelistedTokens 数组中仍然存在(历史记录)
+ • 但所有配置和权限已清除
+ • 如需重新添加,需要再次调用 setWhitelistedToken()
+
+4. 最佳实践:
+ • 提前公告,给用户足够时间移除流动性
+ • 移除前暂停该代币的新增流动性
+ • 记录剩余余额,在紧急模式下安全提取
+ • 移除后验证AUM计算正确
+
+核心合约职责:
+合约 职责 关键功能
+YTRewardRouter 用户入口 接收用户请求,处理代币转移
+YTPoolManager 流动性管理 计算ytLP,管理AUM
+YTVault 资金池 存储资产,执行swap,管理手续费
+YTPriceFeed 价格预言机 提供价格,应用价差
+USDY 计价代币 内部记账单位
+YTLPToken LP代币 代表用户份额
+
diff --git a/document/ytLp用户前端交互文档.md b/document/ytLp用户前端交互文档.md
new file mode 100644
index 0000000..ce07b9e
--- /dev/null
+++ b/document/ytLp用户前端交互文档.md
@@ -0,0 +1,231 @@
+ytLp用户前端交互文档
+1.用户添加流动性
+Solidity
+function addLiquidity(
+ address _token, //YT代币或WUSD地址
+ uint256 _amount, //代币数量
+ uint256 _minUsdy, //最小USDY数量
+ uint256 _minYtLP //最小ytLP数量
+)
+_minUsdy和_minYtLP计算方式(滑点可以让用户在界面选择)
+TypeScript
+/**
+ * 计算添加流动性的 _minUsdy 和 _minYtLP 参数
+ * @param {string} token - 代币地址
+ * @param {BigNumber} amount - 代币数量
+ * @param {number} slippageTolerance - 滑点容忍度 (0.005 = 0.5%)
+ * @returns {Promise<{minUsdy, minYtLP, expectedYtLP, feeInfo}>}
+ */
+async function calculateAddLiquidityParams(token, amount, slippageTolerance = 0.005) {
+ const PRICE_PRECISION = ethers.BigNumber.from("1000000000000000000000000000000");
+ const BASIS_POINTS = 10000;
+
+ try {
+ // 1. 获取价格(使用MinPrice)
+ const tokenPrice = await ytVault.getMinPrice(token);
+
+ // 2. 计算理论USDY(扣费前)
+ const theoreticalUsdy = amount.mul(tokenPrice).div(PRICE_PRECISION);
+
+ // 3. 获取手续费率
+ const feeBasisPoints = await ytVault.getSwapFeeBasisPoints(
+ token,
+ USDY_ADDRESS,
+ theoreticalUsdy
+ );
+
+ // 4. 计算扣费后的代币和USDY
+ const amountAfterFees = amount
+ .mul(BASIS_POINTS - feeBasisPoints)
+ .div(BASIS_POINTS);
+
+ const usdyAmount = amountAfterFees.mul(tokenPrice).div(PRICE_PRECISION);
+
+ // 5. 获取AUM和供应量
+ const [aum, ytLPSupply] = await Promise.all([
+ ytPoolManager.getAumInUsdy(true), // 使用MaxPrice
+ ytLP.totalSupply()
+ ]);
+
+ // 6. 计算预期ytLP
+ let expectedYtLP;
+ if (ytLPSupply.eq(0)) {
+ expectedYtLP = usdyAmount;
+ } else {
+ expectedYtLP = usdyAmount.mul(ytLPSupply).div(aum);
+ }
+
+ // 7. 应用滑点
+ const minUsdy = usdyAmount.mul(
+ ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
+ ).div(10000);
+
+ const minYtLP = expectedYtLP.mul(
+ ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
+ ).div(10000);
+
+ return {
+ minUsdy,
+ minYtLP,
+ expectedYtLP,
+ usdyAmount,
+ feeInfo: {
+ feeBasisPoints: feeBasisPoints.toNumber(),
+ feeAmount: amount.sub(amountAfterFees),
+ amountAfterFees
+ },
+ priceInfo: {
+ tokenPrice: ethers.utils.formatUnits(tokenPrice, 30),
+ aum: ethers.utils.formatEther(aum),
+ ytLPSupply: ethers.utils.formatEther(ytLPSupply)
+ }
+ };
+ } catch (error) {
+ console.error("计算添加流动性参数失败:", error);
+ throw error;
+ }
+}
+
+2.用户移除流动性
+Solidity
+function removeLiquidity(
+ address _tokenOut, //出代币地址
+ uint256 _ytLPAmount, //ytLP数量
+ uint256 _minOut, //最小输出数量
+ address _receiver //接收地址
+)
+_minOut计算方式(滑点可以让用户在界面选择)
+TypeScript
+/**
+ * 计算移除流动性的 _minOut 参数
+ * @param {string} tokenOut - 目标代币地址
+ * @param {BigNumber} ytLPAmount - ytLP数量
+ * @param {number} slippageTolerance - 滑点容忍度 (0.01 = 1%)
+ * @returns {Promise<{minOut, expectedOut, feeBps, priceInfo}>}
+ */
+async function calculateMinOut(tokenOut, ytLPAmount, slippageTolerance = 0.01) {
+ const PRICE_PRECISION = ethers.BigNumber.from("1000000000000000000000000000000");
+ const BASIS_POINTS = 10000;
+
+ try {
+ // 1. 获取AUM和供应量
+ const [aum, ytLPSupply] = await Promise.all([
+ ytPoolManager.getAumInUsdy(false),
+ ytLP.totalSupply()
+ ]);
+
+ // 2. 计算USDY价值
+ const usdyAmount = ytLPAmount.mul(aum).div(ytLPSupply);
+
+ // 3. 获取代币价格和手续费(并行查询)
+ const [tokenPrice, feeBasisPoints] = await Promise.all([
+ ytVault.getMaxPrice(tokenOut),
+ ytVault.getRedemptionFeeBasisPoints(tokenOut, usdyAmount)
+ ]);
+
+ // 4. 计算理论输出
+ const theoreticalOut = usdyAmount.mul(PRICE_PRECISION).div(tokenPrice);
+
+ // 5. 扣除手续费
+ const expectedOut = theoreticalOut
+ .mul(BASIS_POINTS - feeBasisPoints)
+ .div(BASIS_POINTS);
+
+ // 6. 应用滑点
+ const minOut = expectedOut.mul(
+ ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
+ ).div(10000);
+
+ return {
+ minOut,
+ expectedOut,
+ theoreticalOut,
+ usdyAmount,
+ feeBasisPoints: feeBasisPoints.toNumber(),
+ priceInfo: {
+ tokenPrice: ethers.utils.formatUnits(tokenPrice, 30),
+ aum: ethers.utils.formatEther(aum),
+ ytLPSupply: ethers.utils.formatEther(ytLPSupply)
+ }
+ };
+ } catch (error) {
+ console.error("计算_minOut失败:", error);
+ throw error;
+ }
+}
+
+3.用户交换代币
+TypeScript
+function swapYT(
+ address _tokenIn, //输入代币地址
+ address _tokenOut, //输出代币地址
+ uint256 _amountIn, //输入数量
+ uint256 _minOut, //最小输出数量
+ address _receiver //接收地址
+)
+_minOut计算方式(滑点可以让用户在界面选择)
+TypeScript
+/**
+ * 计算 swapYT 的 _minOut 参数
+ * @param {string} tokenIn - 输入代币地址
+ * @param {string} tokenOut - 输出代币地址
+ * @param {BigNumber} amountIn - 输入数量
+ * @param {number} slippageTolerance - 滑点容忍度 (0.005 = 0.5%)
+ * @returns {Promise<{minOut, expectedOut, feeInfo, priceInfo}>}
+ */
+async function calculateSwapMinOut(tokenIn, tokenOut, amountIn, slippageTolerance = 0.005) {
+ const PRICE_PRECISION = ethers.BigNumber.from("1000000000000000000000000000000");
+ const BASIS_POINTS = 10000;
+
+ try {
+ // 1. 获取价格(并行查询)
+ const [priceIn, priceOut] = await Promise.all([
+ ytVault.getMinPrice(tokenIn), // 输入用MinPrice
+ ytVault.getMaxPrice(tokenOut) // 输出用MaxPrice
+ ]);
+
+ // 2. 计算USDY价值
+ const usdyAmount = amountIn.mul(priceIn).div(PRICE_PRECISION);
+
+ // 3. 获取手续费率
+ const feeBasisPoints = await ytVault.getSwapFeeBasisPoints(
+ tokenIn,
+ tokenOut,
+ usdyAmount
+ );
+
+ // 4. 计算理论输出
+ const theoreticalOut = usdyAmount.mul(PRICE_PRECISION).div(priceOut);
+
+ // 5. 扣除手续费
+ const expectedOut = theoreticalOut
+ .mul(BASIS_POINTS - feeBasisPoints)
+ .div(BASIS_POINTS);
+
+ // 6. 应用滑点
+ const minOut = expectedOut.mul(
+ ethers.BigNumber.from(Math.floor((1 - slippageTolerance) * 10000))
+ ).div(10000);
+
+ return {
+ minOut,
+ expectedOut,
+ theoreticalOut,
+ usdyAmount,
+ feeBasisPoints: feeBasisPoints.toNumber(),
+ priceInfo: {
+ priceIn: ethers.utils.formatUnits(priceIn, 30),
+ priceOut: ethers.utils.formatUnits(priceOut, 30),
+ effectiveRate: theoreticalOut.mul(10000).div(amountIn).toNumber() / 100
+ },
+ feeInfo: {
+ feeBps: feeBasisPoints.toNumber(),
+ feeAmount: theoreticalOut.sub(expectedOut)
+ }
+ };
+ } catch (error) {
+ console.error("计算 _minOut 失败:", error);
+ throw error;
+ }
+}
+
diff --git a/document/合约文档.md b/document/合约文档.md
new file mode 100644
index 0000000..62a1200
--- /dev/null
+++ b/document/合约文档.md
@@ -0,0 +1,7000 @@
+合约文档
+测试网络
+arb sepolia
+测试私钥
+0xa082a7037105ebd606bee80906687e400d89899bbb6ba0273a61528c2f5fab89
+合约地址
+YTAssetFactory:0x6DaB73519DbaFf23F36FEd24110e2ef5Cfc8aAC9
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAddress",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidHardCap",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableInvalidOwner",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "VaultNotExists",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "newDefaultHardCap",
+ "type": "uint256"
+ }
+ ],
+ "name": "DefaultHardCapSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "vault",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "newHardCap",
+ "type": "uint256"
+ }
+ ],
+ "name": "HardCapSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "vault",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "redemptionTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "NextRedemptionTimeSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "vault",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wusdPrice",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "ytPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "PricesUpdated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "vault",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "manager",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "name",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "string",
+ "name": "symbol",
+ "type": "string"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "hardCap",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "index",
+ "type": "uint256"
+ }
+ ],
+ "name": "VaultCreated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "VaultImplementationUpdated",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "allVaults",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "_name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_hardCap",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_wusd",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_redemptionTime",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_initialWusdPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_initialYtPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "createVault",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "vault",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string[]",
+ "name": "_names",
+ "type": "string[]"
+ },
+ {
+ "internalType": "string[]",
+ "name": "_symbols",
+ "type": "string[]"
+ },
+ {
+ "internalType": "address[]",
+ "name": "_managers",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_hardCaps",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "address",
+ "name": "_wusd",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_redemptionTimes",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_initialWusdPrices",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_initialYtPrices",
+ "type": "uint256[]"
+ }
+ ],
+ "name": "createVaultBatch",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "vaults",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "defaultHardCap",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getAllVaults",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getVaultCount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ }
+ ],
+ "name": "getVaultInfo",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "exists",
+ "type": "bool"
+ },
+ {
+ "internalType": "uint256",
+ "name": "totalAssets",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "idleAssets",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "managedAssets",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "totalSupply",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "hardCap",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "wusdPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "ytPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "nextRedemptionTime",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_start",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_end",
+ "type": "uint256"
+ }
+ ],
+ "name": "getVaults",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "vaults",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vaultImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_defaultHardCap",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isVault",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_defaultHardCap",
+ "type": "uint256"
+ }
+ ],
+ "name": "setDefaultHardCap",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_hardCap",
+ "type": "uint256"
+ }
+ ],
+ "name": "setHardCap",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_vaults",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_hardCaps",
+ "type": "uint256[]"
+ }
+ ],
+ "name": "setHardCapBatch",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "setVaultImplementation",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ }
+ ],
+ "name": "setVaultManager",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_nextRedemptionTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "setVaultNextRedemptionTime",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_vaults",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_nextRedemptionTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "setVaultNextRedemptionTimeBatch",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_wusdPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_ytPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "updateVaultPrices",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_vaults",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_wusdPrices",
+ "type": "uint256[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_ytPrices",
+ "type": "uint256[]"
+ }
+ ],
+ "name": "updateVaultPricesBatch",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeVault",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_vaults",
+ "type": "address[]"
+ },
+ {
+ "internalType": "address",
+ "name": "_newImplementation",
+ "type": "address"
+ }
+ ],
+ "name": "upgradeVaultBatch",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "vaultImplementation",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
+
+YT-A:0x0cA35994F033685E7a57ef9bc5d00dd3cf927330
+YT-B:0x333805C9EE75f59Aa2Cc79DfDe2499F920c7b408
+YT-C:0x6DF0ED6f0345F601A206974973dE9fC970598587
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "allowance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientAllowance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "balance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientBalance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "approver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidApprover",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidReceiver",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSender",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSpender",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Forbidden",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "HardCapExceeded",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InsufficientWUSD",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InsufficientYTA",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAmount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidHardCap",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidPrice",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ReentrancyGuardReentrantCall",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "SafeERC20FailedOperation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "StillInLockPeriod",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "AssetsDeposited",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "AssetsWithdrawn",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wusdAmount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "ytAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Buy",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "newHardCap",
+ "type": "uint256"
+ }
+ ],
+ "name": "HardCapSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newManager",
+ "type": "address"
+ }
+ ],
+ "name": "ManagerSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "newRedemptionTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "NextRedemptionTimeSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wusdPrice",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "ytPrice",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "timestamp",
+ "type": "uint256"
+ }
+ ],
+ "name": "PriceUpdated",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "user",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "ytAmount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "wusdAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "Sell",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "PRICE_PRECISION",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "canRedeemNow",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "depositManagedAssets",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_wusdAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "depositYT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "ytAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "factory",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getTimeUntilNextRedemption",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "remainingTime",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getVaultInfo",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "_totalAssets",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_idleAssets",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_managedAssets",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_totalSupply",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_hardCap",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_wusdPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_ytPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_nextRedemptionTime",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "hardCap",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "idleAssets",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "_name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbol",
+ "type": "string"
+ },
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_hardCap",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_wusd",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_redemptionTime",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_initialWusdPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_initialYtPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "managedAssets",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "manager",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "nextRedemptionTime",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_wusdAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "previewBuy",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "ytAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_ytAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "previewSell",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "wusdAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_hardCap",
+ "type": "uint256"
+ }
+ ],
+ "name": "setHardCap",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ }
+ ],
+ "name": "setManager",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_nextRedemptionTime",
+ "type": "uint256"
+ }
+ ],
+ "name": "setNextRedemptionTime",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalAssets",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_wusdPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_ytPrice",
+ "type": "uint256"
+ }
+ ],
+ "name": "updatePrices",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawForManagement",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_ytAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawYT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "wusdAmount",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wusdAddress",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wusdPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ytPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
+
+WUSD(fork 测试用):0x939cf46F7A4d05da2a37213E7379a8b04528F590
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "allowance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientAllowance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "balance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientBalance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "approver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidApprover",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidReceiver",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSender",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSpender",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableInvalidOwner",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "string",
+ "name": "_name",
+ "type": "string"
+ },
+ {
+ "internalType": "string",
+ "name": "_symbol",
+ "type": "string"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+]
+
+USDY:0x631Bd6834C50f6d2B07035c9253b4a19132E888c
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "allowance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientAllowance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "balance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientBalance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "approver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidApprover",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidReceiver",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSender",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSpender",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Forbidden",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidVault",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableInvalidOwner",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "vault",
+ "type": "address"
+ }
+ ],
+ "name": "VaultAdded",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "vault",
+ "type": "address"
+ }
+ ],
+ "name": "VaultRemoved",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ }
+ ],
+ "name": "addVault",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_account",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_vault",
+ "type": "address"
+ }
+ ],
+ "name": "removeVault",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "vaults",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
+
+YTLPToken:0x1b96F219E8aeE557DD8bD905a6c72cc64eA5BD7B
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "allowance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientAllowance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "balance",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "needed",
+ "type": "uint256"
+ }
+ ],
+ "name": "ERC20InsufficientBalance",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "approver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidApprover",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "receiver",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidReceiver",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "sender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSender",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "ERC20InvalidSpender",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidMinter",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotMinter",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableInvalidOwner",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "OwnableUnauthorizedAccount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Approval",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "minter",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "isActive",
+ "type": "bool"
+ }
+ ],
+ "name": "MinterSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "previousOwner",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "OwnershipTransferred",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "Transfer",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "owner",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ }
+ ],
+ "name": "allowance",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "spender",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "approve",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ }
+ ],
+ "name": "balanceOf",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_from",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "burn",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "decimals",
+ "outputs": [
+ {
+ "internalType": "uint8",
+ "name": "",
+ "type": "uint8"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isMinter",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "mint",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "name",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "owner",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "renounceOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_minter",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "_isActive",
+ "type": "bool"
+ }
+ ],
+ "name": "setMinter",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "symbol",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalSupply",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transfer",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "from",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "to",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "value",
+ "type": "uint256"
+ }
+ ],
+ "name": "transferFrom",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newOwner",
+ "type": "address"
+ }
+ ],
+ "name": "transferOwnership",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ }
+]
+
+YTPriceFeed:0x0f2d930EE73972132E3a36b7eD6F709Af6E5B879
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Forbidden",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "MaxChangeTooHigh",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "PriceChangeTooLarge",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "SpreadTooHigh",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "keeper",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "isActive",
+ "type": "bool"
+ }
+ ],
+ "name": "KeeperSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "oldPrice",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "newPrice",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "timestamp",
+ "type": "uint256"
+ }
+ ],
+ "name": "PriceUpdate",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "spreadBps",
+ "type": "uint256"
+ }
+ ],
+ "name": "SpreadUpdate",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "BASIS_POINTS_DIVISOR",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_SPREAD_BASIS_POINTS",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "PRICE_PRECISION",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "WUSD",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_price",
+ "type": "uint256"
+ }
+ ],
+ "name": "forceUpdatePrice",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "getMaxPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "getMinPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "_maximise",
+ "type": "bool"
+ }
+ ],
+ "name": "getPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "getPriceInfo",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "currentPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "cachedPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "maxPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "minPrice",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "spread",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "gov",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isKeeper",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "lastPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "maxPriceChangeBps",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_keeper",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "_isActive",
+ "type": "bool"
+ }
+ ],
+ "name": "setKeeper",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_maxPriceChangeBps",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxPriceChangeBps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_spreadBasisPoints",
+ "type": "uint256"
+ }
+ ],
+ "name": "setSpreadBasisPoints",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address[]",
+ "name": "_tokens",
+ "type": "address[]"
+ },
+ {
+ "internalType": "uint256[]",
+ "name": "_spreadBasisPoints",
+ "type": "uint256[]"
+ }
+ ],
+ "name": "setSpreadBasisPointsForMultiple",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_wusdPriceSource",
+ "type": "address"
+ }
+ ],
+ "name": "setWusdPriceSource",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "spreadBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "updatePrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "wusdPriceSource",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
+
+YTVault:0x19982e5145ca5401A1084c0BF916c0E0bB343Af9
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "AmountExceedsLimit",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "DailyLimitExceeded",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "EmergencyMode",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Forbidden",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InsufficientPool",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InsufficientUSDYAmount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAddress",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAmount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidFee",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidPoolAmount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "MaxUSDYExceeded",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInEmergency",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotSwapper",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "OnlyPoolManager",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ReentrancyGuardReentrantCall",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "SafeERC20FailedOperation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "SameToken",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "SlippageTooHigh",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "SwapDisabled",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "TokenNotWhitelisted",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "usdyAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "AddLiquidity",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "enabled",
+ "type": "bool"
+ }
+ ],
+ "name": "EmergencyModeSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "usdyAmount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amountOut",
+ "type": "uint256"
+ }
+ ],
+ "name": "RemoveLiquidity",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenIn",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "tokenOut",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amountIn",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amountOut",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "feeBasisPoints",
+ "type": "uint256"
+ }
+ ],
+ "name": "Swap",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "enabled",
+ "type": "bool"
+ }
+ ],
+ "name": "SwapEnabledSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "BASIS_POINTS_DIVISOR",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "PRICE_PRECISION",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "USDY_DECIMALS",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "name": "allWhitelistedTokens",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "buyUSDY",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "clearWhitelistedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "emergencyMode",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getAllPoolTokens",
+ "outputs": [
+ {
+ "internalType": "address[]",
+ "name": "",
+ "type": "address[]"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_usdyDelta",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_feeBasisPoints",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_taxBasisPoints",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "_increment",
+ "type": "bool"
+ }
+ ],
+ "name": "getFeeBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "getMaxPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "getMinPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_maximise",
+ "type": "bool"
+ }
+ ],
+ "name": "getPoolValue",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "_maximise",
+ "type": "bool"
+ }
+ ],
+ "name": "getPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_usdyAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "getRedemptionFeeBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_tokenIn",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_tokenOut",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_usdyAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "getSwapFeeBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ }
+ ],
+ "name": "getTargetUsdyAmount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "gov",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "hasDynamicFees",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_usdy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_priceFeed",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "isSwapEnabled",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isSwapper",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "maxSwapAmount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "maxSwapSlippageBps",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "maxUsdyAmounts",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "poolAmounts",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "priceFeed",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "sellUSDY",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_hasDynamicFees",
+ "type": "bool"
+ }
+ ],
+ "name": "setDynamicFees",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_emergencyMode",
+ "type": "bool"
+ }
+ ],
+ "name": "setEmergencyMode",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_gov",
+ "type": "address"
+ }
+ ],
+ "name": "setGov",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxSwapAmount",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_slippageBps",
+ "type": "uint256"
+ }
+ ],
+ "name": "setMaxSwapSlippageBps",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_manager",
+ "type": "address"
+ }
+ ],
+ "name": "setPoolManager",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_isSwapEnabled",
+ "type": "bool"
+ }
+ ],
+ "name": "setSwapEnabled",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_swapFee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_stableSwapFee",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_taxBasisPoints",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_stableTaxBasisPoints",
+ "type": "uint256"
+ }
+ ],
+ "name": "setSwapFees",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_swapper",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "_isActive",
+ "type": "bool"
+ }
+ ],
+ "name": "setSwapper",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_decimals",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_weight",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_maxUsdyAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "bool",
+ "name": "_isStable",
+ "type": "bool"
+ }
+ ],
+ "name": "setWhitelistedToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "stableSwapFeeBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "stableTaxBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "stableTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_tokenIn",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_tokenOut",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "swap",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "swapFeeBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "taxBasisPoints",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "tokenBalances",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "tokenDecimals",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "tokenWeights",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "totalTokenWeights",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "usdy",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "usdyAmounts",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "whitelistedTokens",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ }
+ ],
+ "name": "withdrawToken",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ytPoolManager",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
+
+YTPoolManager:0x14246886a1E1202cb6b5a2db793eF3359d536302
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "CooldownNotPassed",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Forbidden",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InsufficientOutput",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAddress",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAmount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidDuration",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "PrivateMode",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ReentrancyGuardReentrantCall",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "SafeERC20FailedOperation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "aumInUsdy",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "ytLPSupply",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "usdyAmount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "mintAmount",
+ "type": "uint256"
+ }
+ ],
+ "name": "AddLiquidity",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "duration",
+ "type": "uint256"
+ }
+ ],
+ "name": "CooldownDurationSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "handler",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "bool",
+ "name": "isActive",
+ "type": "bool"
+ }
+ ],
+ "name": "HandlerSet",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "ytLPAmount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "aumInUsdy",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "ytLPSupply",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "usdyAmount",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amountOut",
+ "type": "uint256"
+ }
+ ],
+ "name": "RemoveLiquidity",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "BASIS_POINTS_DIVISOR",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "MAX_COOLDOWN_DURATION",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "PRICE_PRECISION",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "YTLP_PRECISION",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_fundingAccount",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_account",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_minUsdy",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_minYtLP",
+ "type": "uint256"
+ }
+ ],
+ "name": "addLiquidityForAccount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "aumAddition",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "aumDeduction",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "cooldownDuration",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_maximise",
+ "type": "bool"
+ }
+ ],
+ "name": "getAumInUsdy",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bool",
+ "name": "_maximise",
+ "type": "bool"
+ }
+ ],
+ "name": "getPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "gov",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_ytVault",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_usdy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_ytLP",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_cooldownDuration",
+ "type": "uint256"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "isHandler",
+ "outputs": [
+ {
+ "internalType": "bool",
+ "name": "",
+ "type": "bool"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "name": "lastAddedAt",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_account",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_tokenOut",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_ytLPAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_minOut",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "removeLiquidityForAccount",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_addition",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_deduction",
+ "type": "uint256"
+ }
+ ],
+ "name": "setAumAdjustment",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "uint256",
+ "name": "_duration",
+ "type": "uint256"
+ }
+ ],
+ "name": "setCooldownDuration",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_gov",
+ "type": "address"
+ }
+ ],
+ "name": "setGov",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_handler",
+ "type": "address"
+ },
+ {
+ "internalType": "bool",
+ "name": "_isActive",
+ "type": "bool"
+ }
+ ],
+ "name": "setHandler",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "usdy",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ytLP",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ytVault",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
+
+YTRewardRouter:0x51eEF57eC57c867AC23945f0ce21aA5A9a2C246c
+JSON
+[
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "target",
+ "type": "address"
+ }
+ ],
+ "name": "AddressEmptyCode",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "AlreadyInitialized",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "ERC1967InvalidImplementation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ERC1967NonPayable",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "FailedCall",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "Forbidden",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InsufficientOutput",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAddress",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidAmount",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "InvalidInitialization",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "NotInitializing",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "ReentrancyGuardReentrantCall",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "token",
+ "type": "address"
+ }
+ ],
+ "name": "SafeERC20FailedOperation",
+ "type": "error"
+ },
+ {
+ "inputs": [],
+ "name": "UUPSUnauthorizedCallContext",
+ "type": "error"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "bytes32",
+ "name": "slot",
+ "type": "bytes32"
+ }
+ ],
+ "name": "UUPSUnsupportedProxiableUUID",
+ "type": "error"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": false,
+ "internalType": "uint64",
+ "name": "version",
+ "type": "uint64"
+ }
+ ],
+ "name": "Initialized",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "account",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "tokenIn",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "address",
+ "name": "tokenOut",
+ "type": "address"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amountIn",
+ "type": "uint256"
+ },
+ {
+ "indexed": false,
+ "internalType": "uint256",
+ "name": "amountOut",
+ "type": "uint256"
+ }
+ ],
+ "name": "Swap",
+ "type": "event"
+ },
+ {
+ "anonymous": false,
+ "inputs": [
+ {
+ "indexed": true,
+ "internalType": "address",
+ "name": "implementation",
+ "type": "address"
+ }
+ ],
+ "name": "Upgraded",
+ "type": "event"
+ },
+ {
+ "inputs": [],
+ "name": "UPGRADE_INTERFACE_VERSION",
+ "outputs": [
+ {
+ "internalType": "string",
+ "name": "",
+ "type": "string"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_token",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_minUsdy",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_minYtLP",
+ "type": "uint256"
+ }
+ ],
+ "name": "addLiquidity",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_account",
+ "type": "address"
+ }
+ ],
+ "name": "getAccountValue",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "getYtLPPrice",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "gov",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_usdy",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_ytLP",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_ytPoolManager",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_ytVault",
+ "type": "address"
+ }
+ ],
+ "name": "initialize",
+ "outputs": [],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "proxiableUUID",
+ "outputs": [
+ {
+ "internalType": "bytes32",
+ "name": "",
+ "type": "bytes32"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_tokenOut",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_ytLPAmount",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_minOut",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "removeLiquidity",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "_tokenIn",
+ "type": "address"
+ },
+ {
+ "internalType": "address",
+ "name": "_tokenOut",
+ "type": "address"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_amountIn",
+ "type": "uint256"
+ },
+ {
+ "internalType": "uint256",
+ "name": "_minOut",
+ "type": "uint256"
+ },
+ {
+ "internalType": "address",
+ "name": "_receiver",
+ "type": "address"
+ }
+ ],
+ "name": "swapYT",
+ "outputs": [
+ {
+ "internalType": "uint256",
+ "name": "",
+ "type": "uint256"
+ }
+ ],
+ "stateMutability": "nonpayable",
+ "type": "function"
+ },
+ {
+ "inputs": [
+ {
+ "internalType": "address",
+ "name": "newImplementation",
+ "type": "address"
+ },
+ {
+ "internalType": "bytes",
+ "name": "data",
+ "type": "bytes"
+ }
+ ],
+ "name": "upgradeToAndCall",
+ "outputs": [],
+ "stateMutability": "payable",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "usdy",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ytLP",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ytPoolManager",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ },
+ {
+ "inputs": [],
+ "name": "ytVault",
+ "outputs": [
+ {
+ "internalType": "address",
+ "name": "",
+ "type": "address"
+ }
+ ],
+ "stateMutability": "view",
+ "type": "function"
+ }
+]
+
+部署及权限文件
+[deployments-vault-system.json]
+
+{
+ "network": "arbSepolia",
+ "chainId": "421614",
+ "deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "timestamp": "2025-12-15T08:56:02.155Z",
+ "wusdAddress": "0x939cf46F7A4d05da2a37213E7379a8b04528F590",
+ "defaultHardCap": "10000000000000000000000000",
+ "contracts": {
+ "YTAssetVault": {
+ "implementation": "0x6cBD32731742004471ce16FcB80a6db0844E8b13"
+ },
+ "YTAssetFactory": {
+ "proxy": "0x6DaB73519DbaFf23F36FEd24110e2ef5Cfc8aAC9",
+ "implementation": "0xc22a07Cf4bbDc323bC3288a82E85d1367a470b75"
+ }
+ },
+ "vaults": [
+ {
+ "name": "YT Token A",
+ "symbol": "YT-A",
+ "address": "0x0cA35994F033685E7a57ef9bc5d00dd3cf927330",
+ "index": "0",
+ "manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "hardCap": "10000000000000000000000000",
+ "redemptionTime": 1797324969,
+ "wusdPrice": "1000000000000000000000000000000",
+ "ytPrice": "1000000000000000000000000000000"
+ },
+ {
+ "name": "YT Token B",
+ "symbol": "YT-B",
+ "address": "0x333805C9EE75f59Aa2Cc79DfDe2499F920c7b408",
+ "index": "1",
+ "manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "hardCap": "10000000000000000000000000",
+ "redemptionTime": 1797324969,
+ "wusdPrice": "1000000000000000000000000000000",
+ "ytPrice": "1000000000000000000000000000000"
+ },
+ {
+ "name": "YT Token C",
+ "symbol": "YT-C",
+ "address": "0x6DF0ED6f0345F601A206974973dE9fC970598587",
+ "index": "2",
+ "manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "hardCap": "10000000000000000000000000",
+ "redemptionTime": 1797324969,
+ "wusdPrice": "1000000000000000000000000000000",
+ "ytPrice": "1000000000000000000000000000000"
+ }
+ ],
+ "lastUpdate": "2025-12-15T08:56:22.614Z"
+}
+
+
+[deployments-wusd.json]
+
+
+{
+ "network": "arbSepolia",
+ "chainId": "421614",
+ "deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "timestamp": "2025-12-15T08:53:30.301Z",
+ "contracts": {
+ "WUSD": {
+ "proxy": "0x939cf46F7A4d05da2a37213E7379a8b04528F590",
+ "implementation": "0xA6674E25670563f881aABCc25845757cEecb8d86",
+ "name": "Wrapped USD",
+ "symbol": "WUSD",
+ "decimals": 18
+ }
+ }
+}
+
+
+
+[deployments-ytlp.json]
+
+
+{
+ "network": "arbSepolia",
+ "chainId": "421614",
+ "deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "timestamp": "2025-12-15T08:55:35.962Z",
+ "contracts": {
+ "USDY": {
+ "proxy": "0x631Bd6834C50f6d2B07035c9253b4a19132E888c",
+ "implementation": "0xb14d186d4EAcE8131a449126c6208165a3F5FC5b"
+ },
+ "YTLPToken": {
+ "proxy": "0x1b96F219E8aeE557DD8bD905a6c72cc64eA5BD7B",
+ "implementation": "0x0C3fa01b2D0596B4190edEF1B77534237231C77e"
+ },
+ "YTPriceFeed": {
+ "proxy": "0x0f2d930EE73972132E3a36b7eD6F709Af6E5B879",
+ "implementation": "0x2201c2B382E1decD933fc8d3503bEcE221B6C46c"
+ },
+ "YTVault": {
+ "proxy": "0x19982e5145ca5401A1084c0BF916c0E0bB343Af9",
+ "implementation": "0x61278a2EBFC07eF0F7f84407291aAD07DA596AB2"
+ },
+ "YTPoolManager": {
+ "proxy": "0x14246886a1E1202cb6b5a2db793eF3359d536302",
+ "implementation": "0x96Fe19188c3c7d0EDA441dafC7976fBB3526d28c"
+ },
+ "YTRewardRouter": {
+ "proxy": "0x51eEF57eC57c867AC23945f0ce21aA5A9a2C246c",
+ "implementation": "0x3688CDd7A25613E7b1E7E0ee1aA46c21F66D27F3"
+ }
+ }
+}
+
+
+
+[deployments-ytlp-config.json]
+
+{
+ "network": "arbSepolia",
+ "chainId": "421614",
+ "configurer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "timestamp": "2025-12-15T08:57:09.075Z",
+ "configuration": {
+ "permissions": {
+ "usdyVaults": [
+ "0x19982e5145ca5401A1084c0BF916c0E0bB343Af9",
+ "0x14246886a1E1202cb6b5a2db793eF3359d536302"
+ ],
+ "ytlpMinters": [
+ "0x14246886a1E1202cb6b5a2db793eF3359d536302"
+ ],
+ "vaultPoolManager": "0x14246886a1E1202cb6b5a2db793eF3359d536302",
+ "vaultSwappers": [
+ "0x51eEF57eC57c867AC23945f0ce21aA5A9a2C246c"
+ ],
+ "poolManagerHandlers": [
+ "0x51eEF57eC57c867AC23945f0ce21aA5A9a2C246c"
+ ],
+ "priceFeedKeepers": [
+ "0xa013422A5918CD099C63c8CC35283EACa99a705d"
+ ],
+ "priceFeedWusdSource": "0x0cA35994F033685E7a57ef9bc5d00dd3cf927330"
+ },
+ "parameters": {
+ "dynamicFees": true,
+ "maxSwapSlippageBps": 1000,
+ "maxPriceChangeBps": 500
+ }
+ }
+}
+
+
+[deployments-whitelist-config.json]
+
+{
+ "timestamp": "2025-12-15T08:57:53.055Z",
+ "operator": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
+ "whitelistedVaults": [
+ {
+ "name": "YT Token A",
+ "symbol": "YT-A",
+ "address": "0x0cA35994F033685E7a57ef9bc5d00dd3cf927330",
+ "weight": 4000,
+ "maxUsdyAmount": "45000000000000000000000000",
+ "price": "1000000000000000000000000000000"
+ },
+ {
+ "name": "YT Token B",
+ "symbol": "YT-B",
+ "address": "0x333805C9EE75f59Aa2Cc79DfDe2499F920c7b408",
+ "weight": 3000,
+ "maxUsdyAmount": "35000000000000000000000000",
+ "price": "1000000000000000000000000000000"
+ },
+ {
+ "name": "YT Token C",
+ "symbol": "YT-C",
+ "address": "0x6DF0ED6f0345F601A206974973dE9fC970598587",
+ "weight": 2000,
+ "maxUsdyAmount": "25000000000000000000000000",
+ "price": "1000000000000000000000000000000"
+ }
+ ],
+ "totalWeight": "9000",
+ "wusdPriceSource": "0x0cA35994F033685E7a57ef9bc5d00dd3cf927330"
+}
+
+
+相关文档
+ytLp池子合约流程文档
+ytLp用户前端交互文档
+ytLp流动性池系统操作流程文档
+Vault金库系统操作流程文档