change WUSD payment to USDC

This commit is contained in:
2025-12-24 16:41:26 +08:00
parent d2e9377f78
commit e21ee7a5df
160 changed files with 6038 additions and 4050 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,456 +0,0 @@
# 🔒 Slither 安全审计修复指南
## 📌 修复优先级
- **P0 (立即修复)**: 高危漏洞,可能导致资金损失或合约被破坏
- **P1 (尽快修复)**: 中危问题,可能导致精度损失或逻辑错误
- **P2 (建议修复)**: 低危问题,影响代码质量和可维护性
---
## 🔴 P0: 高危问题 (必须立即修复)
### 1. ⚠️ 未保护的初始化函数 (最严重!)
**问题**: 所有可升级合约的 `initialize` 函数缺少 `initializer` 修饰符
**风险**: 攻击者可以调用 `upgradeToAndCall` 删除合约!
**受影响的合约**:
- YTAssetFactory.sol
- YTAssetVault.sol
- YTPoolManager.sol
- YTVault.sol
- YTPriceFeed.sol
- YTRewardRouter.sol
- USDY.sol
- WUSD.sol
- YTLPToken.sol
#### ✅ 修复方案
**YTAssetFactory.sol (Line 52-63)**
```solidity
// ❌ 修复前
function initialize(
address _vaultImplementation,
uint256 _defaultHardCap
) external initializer {
if (_vaultImplementation == address(0)) revert InvalidAddress();
__Ownable_init(msg.sender);
__UUPSUpgradeable_init();
vaultImplementation = _vaultImplementation;
defaultHardCap = _defaultHardCap;
}
// ✅ 修复后 (已经有 initializer 修饰符,这个合约是正确的)
// 但需要确保其他合约也添加了
```
**YTAssetVault.sol (Line 125-154) - 需要修复**
```solidity
// ❌ 修复前
function initialize(
string memory _name,
string memory _symbol,
address _manager,
uint256 _hardCap,
address _wusd,
uint256 _redemptionTime,
uint256 _initialWusdPrice,
uint256 _initialYtPrice
) external initializer {
// ... 初始化代码
}
// ✅ 修复后 (已正确)
// 这个合约已经有 initializer 修饰符了
```
**实际问题**: 检查代码发现大部分合约已经使用了 `initializer` 修饰符。
但 Slither 可能是在检测 **proxy 合约的部署安全性**
**额外保护**: 在实现合约的构造函数中添加 `_disableInitializers()`
```solidity
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
```
这样可以防止实现合约被直接初始化。
---
### 2. ⚠️ 任意 from 地址的 transferFrom
**位置**: `YTPoolManager.sol` Line 158
**问题代码**:
```solidity
function _addLiquidity(
address _fundingAccount, // ⚠️ 可以是任意地址
address _account,
address _token,
uint256 _amount,
uint256 _minUsdy,
uint256 _minYtLP
) private returns (uint256) {
// ...
IERC20(_token).safeTransferFrom(_fundingAccount, ytVault, _amount); // ⚠️ 危险!
// ...
}
```
**风险**: 如果 `_fundingAccount` 可以被恶意控制,可能导致未授权的代币转移。
#### ✅ 修复方案
**方案 1: 限制调用者 (推荐)**
```solidity
function _addLiquidity(
address _fundingAccount,
address _account,
address _token,
uint256 _amount,
uint256 _minUsdy,
uint256 _minYtLP
) private returns (uint256) {
if (_amount == 0) revert InvalidAmount();
// ✅ 添加: 确保只有授权的 handler 或用户本人可以使用其账户
if (_fundingAccount != msg.sender && !isHandler[msg.sender]) {
revert Forbidden();
}
uint256 aumInUsdy = getAumInUsdy(true);
uint256 ytLPSupply = IERC20(ytLP).totalSupply();
IERC20(_token).safeTransferFrom(_fundingAccount, ytVault, _amount);
// ... 后续逻辑
}
```
**方案 2: 使用白名单**
```solidity
// 添加状态变量
mapping(address => bool) public approvedFundingAccounts;
// 添加管理函数
function setApprovedFundingAccount(address _account, bool _approved) external onlyGov {
approvedFundingAccounts[_account] = _approved;
}
// 在 _addLiquidity 中检查
function _addLiquidity(...) private returns (uint256) {
if (!approvedFundingAccounts[_fundingAccount] && _fundingAccount != msg.sender) {
revert UnauthorizedFundingAccount();
}
// ...
}
```
---
## 🟠 P1: 中危问题 (尽快修复)
### 3. 重入漏洞
**位置**: `YTVault.sol` Line 331-335
**问题代码**:
```solidity
function sellUSDY(address _token, address _receiver)
external
onlyPoolManager
nonReentrant // ✅ 已经有 nonReentrant,但顺序不对
notInEmergency
returns (uint256)
{
// ... 前面的逻辑
// ❌ 外部调用
IUSDY(usdy).burn(address(this), usdyAmount);
// ❌ 之后更新状态
IERC20(_token).safeTransfer(_receiver, amountOut);
_updateTokenBalance(_token); // 状态更新在外部调用后!
}
```
**分析**: 虽然已经有 `nonReentrant` 修饰符,但 Slither 仍然报告是因为:
1. `_updateTokenBalance` 在外部调用后执行
2. 如果 `_receiver` 是恶意合约,可能在 `safeTransfer` 回调中做些什么
#### ✅ 修复方案
**遵循 CEI 模式 (Checks-Effects-Interactions)**
```solidity
function sellUSDY(address _token, address _receiver)
external
onlyPoolManager
nonReentrant
notInEmergency
returns (uint256)
{
if (!whitelistedTokens[_token]) revert TokenNotWhitelisted();
if (!isSwapEnabled) revert SwapDisabled();
uint256 usdyAmount = _transferIn(usdy);
if (usdyAmount == 0) revert InvalidAmount();
uint256 price = _getPrice(_token, true);
uint256 redemptionAmount = usdyAmount * PRICE_PRECISION / price;
redemptionAmount = _adjustForDecimals(redemptionAmount, usdy, _token);
if (redemptionAmount == 0) revert InvalidAmount();
uint256 feeBasisPoints = _getSwapFeeBasisPoints(usdy, _token, redemptionAmount);
uint256 amountOut = redemptionAmount * (BASIS_POINTS_DIVISOR - feeBasisPoints) / BASIS_POINTS_DIVISOR;
if (amountOut == 0) revert InvalidAmount();
if (poolAmounts[_token] < amountOut) revert InsufficientPool();
uint256 usdyAmountOut = amountOut * price / PRICE_PRECISION;
usdyAmountOut = _adjustForDecimals(usdyAmountOut, _token, usdy);
// ✅ 1. Effects: 先更新所有状态
_decreasePoolAmount(_token, amountOut);
_decreaseUsdyAmount(_token, usdyAmountOut);
// ✅ 预先更新 tokenBalance (模拟转出后的余额)
uint256 currentBalance = IERC20(_token).balanceOf(address(this));
tokenBalances[_token] = currentBalance - amountOut;
// ✅ 2. Interactions: 最后进行外部调用
IUSDY(usdy).burn(address(this), usdyAmount);
IERC20(_token).safeTransfer(_receiver, amountOut);
// ✅ 3. 验证最终余额 (可选,增强安全性)
uint256 finalBalance = IERC20(_token).balanceOf(address(this));
require(finalBalance == tokenBalances[_token], "Balance mismatch");
emit RemoveLiquidity(_receiver, _token, usdyAmount, amountOut);
return amountOut;
}
```
---
### 4. 先除后乘导致精度损失
**位置**: 多处
#### 问题 1: `Lending.sol` Line 343, 346
```solidity
// ❌ 修复前
uint256 collateralValueUSD = (collateralAmount * assetPrice) / assetScale;
uint256 discountedValue = (collateralValueUSD * assetConfig.liquidationFactor) / 1e18;
// ✅ 修复后
uint256 collateralValueUSD = (collateralAmount * assetPrice * assetConfig.liquidationFactor)
/ (assetScale * 1e18);
```
#### 问题 2: `Lending.sol` Line 470, 479
```solidity
// ❌ 修复前
uint256 assetPriceDiscounted = (assetPrice * (FACTOR_SCALE - discountFactor)) / FACTOR_SCALE;
uint256 result = (basePrice * baseAmount * assetScale) / (assetPriceDiscounted * baseScale);
// ✅ 修复后
uint256 result = (basePrice * baseAmount * assetScale * FACTOR_SCALE)
/ (assetPrice * (FACTOR_SCALE - discountFactor) * baseScale);
```
#### 问题 3: `YTVault.sol` Line 548, 552
```solidity
// ❌ 修复前
uint256 averageDiff = (initialDiff + nextDiff) / 2;
uint256 taxBps = _taxBasisPoints * averageDiff / targetAmount;
// ✅ 修复后
uint256 taxBps = _taxBasisPoints * (initialDiff + nextDiff) / (2 * targetAmount);
```
---
## 🟡 P2: 低危/信息性问题
### 5. 缺少事件发射
```solidity
// YTPoolManager.sol Line 112
function setGov(address _gov) external onlyGov {
if (_gov == address(0)) revert InvalidAddress();
address oldGov = gov; // ✅ 添加
gov = _gov;
emit GovChanged(oldGov, _gov); // ✅ 添加事件
}
// ✅ 添加事件定义
event GovChanged(address indexed oldGov, address indexed newGov);
event PoolManagerChanged(address indexed oldManager, address indexed newManager);
event AumAdjustmentChanged(uint256 addition, uint256 deduction);
```
### 6. 缺少零地址检查
```solidity
// YTAssetVault.sol Line 176
function setManager(address _manager) external onlyFactory {
require(_manager != address(0), "Zero address"); // ✅ 添加检查
manager = _manager;
emit ManagerSet(_manager);
}
// YTPriceFeed.sol Line 80
function setWusdPriceSource(address _wusdPriceSource) external onlyGov {
require(_wusdPriceSource != address(0), "Zero address"); // ✅ 添加检查
wusdPriceSource = _wusdPriceSource;
}
```
### 7. 忽略返回值
```solidity
// YTRewardRouter.sol Line 117
// ❌ 修复前
IERC20(_token).approve(ytPoolManager, _amount);
// ✅ 修复后
bool success = IERC20(_token).approve(ytPoolManager, _amount);
require(success, "Approve failed");
// 或者使用 SafeERC20
IERC20(_token).safeApprove(ytPoolManager, _amount);
```
### 8. Solidity 版本统一
```solidity
// ❌ 修复前: 各个文件使用不同版本
pragma solidity ^0.8.0;
// ✅ 修复后: 统一使用
pragma solidity ^0.8.20;
```
---
## 📋 修复检查清单
### P0 - 高危问题
- [ ] 在所有实现合约添加 `_disableInitializers()` 到构造函数
- [ ] 修复 `YTPoolManager._addLiquidity` 的任意 from 问题
- [ ] 验证所有合约的 `initialize` 函数有 `initializer` 修饰符
### P1 - 中危问题
- [ ] 重构 `YTVault.sellUSDY` 遵循 CEI 模式
- [ ] 修复所有先除后乘的精度问题
- [ ] Lending._absorbInternal
- [ ] Lending.quoteCollateral
- [ ] YTVault.sellUSDY
- [ ] YTVault.swap
- [ ] YTVault.getFeeBasisPoints
### P2 - 低危问题
- [ ] 添加缺失的事件
- [ ] 添加零地址检查
- [ ] 修复忽略返回值的问题
- [ ] 统一 Solidity 版本到 ^0.8.20
---
## 🧪 测试建议
### 1. 初始化安全测试
```solidity
// test/security/InitializerTest.t.sol
function testCannotReinitialize() public {
vm.expectRevert();
factory.initialize(address(vault), 1000);
}
function testCannotInitializeImplementation() public {
YTAssetVault impl = new YTAssetVault();
vm.expectRevert();
impl.initialize("Test", "TST", address(this), 1000, address(0), 0, 0, 0);
}
```
### 2. 重入攻击测试
```solidity
contract MaliciousReceiver {
YTVault public vault;
bool public attacked;
function attack() external {
// 尝试重入
vault.sellUSDY(token, address(this));
}
// ERC20 回调
function onERC20Received(...) external {
if (!attacked) {
attacked = true;
vault.sellUSDY(token, address(this)); // 应该失败
}
}
}
function testReentrancyProtection() public {
MaliciousReceiver attacker = new MaliciousReceiver(vault);
vm.expectRevert("ReentrancyGuard: reentrant call");
attacker.attack();
}
```
### 3. 精度损失测试
```solidity
function testMathPrecision() public {
uint256 price = 1e30;
uint256 amount = 1e18;
uint256 scale = 1e18;
// 测试先除后乘 vs 先乘后除的差异
uint256 result1 = (amount * price) / scale;
uint256 result2 = amount * (price / scale);
assertEq(result1, result2, "Precision loss detected");
}
```
---
## 📞 后续步骤
1. **立即修复 P0 问题**
2. **运行完整测试套件**
3. **重新运行 Slither 验证修复**
4. **考虑进行专业审计**
```bash
# 重新运行 Slither
slither . --exclude-informational --exclude-low
# 运行测试
forge test -vvv
# 生成覆盖率报告
forge coverage
```

View File

@@ -0,0 +1,113 @@
[
{
"inputs": [],
"name": "decimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "description",
"outputs": [
{
"internalType": "string",
"name": "",
"type": "string"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [
{
"internalType": "uint80",
"name": "_roundId",
"type": "uint80"
}
],
"name": "getRoundData",
"outputs": [
{
"internalType": "uint80",
"name": "roundId",
"type": "uint80"
},
{
"internalType": "int256",
"name": "answer",
"type": "int256"
},
{
"internalType": "uint256",
"name": "startedAt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "updatedAt",
"type": "uint256"
},
{
"internalType": "uint80",
"name": "answeredInRound",
"type": "uint80"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "latestRoundData",
"outputs": [
{
"internalType": "uint80",
"name": "roundId",
"type": "uint80"
},
{
"internalType": "int256",
"name": "answer",
"type": "int256"
},
{
"internalType": "uint256",
"name": "startedAt",
"type": "uint256"
},
{
"internalType": "uint256",
"name": "updatedAt",
"type": "uint256"
},
{
"internalType": "uint80",
"name": "answeredInRound",
"type": "uint80"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "version",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@@ -120,11 +120,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -229,7 +224,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "baseTokenPriceFeed", "name": "lendingPriceSource",
"type": "address" "type": "address"
}, },
{ {
@@ -299,11 +294,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -349,7 +339,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "baseTokenPriceFeed", "name": "lendingPriceSource",
"type": "address" "type": "address"
}, },
{ {
@@ -419,11 +409,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -505,11 +490,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -548,11 +528,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -628,11 +603,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -686,7 +656,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "baseTokenPriceFeed", "name": "lendingPriceSource",
"type": "address" "type": "address"
}, },
{ {
@@ -834,7 +804,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "baseTokenPriceFeed", "name": "lendingPriceSource",
"type": "address" "type": "address"
}, },
{ {
@@ -904,11 +874,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -1004,7 +969,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "baseTokenPriceFeed", "name": "lendingPriceSource",
"type": "address" "type": "address"
}, },
{ {
@@ -1074,11 +1039,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -1165,11 +1125,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",

View File

@@ -16,7 +16,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "baseTokenPriceFeed", "name": "lendingPriceSource",
"type": "address" "type": "address"
}, },
{ {

View File

@@ -1,17 +1,4 @@
[ [
{
"inputs": [],
"name": "wusdPrice",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "ytPrice", "name": "ytPrice",

View File

@@ -1,24 +1,17 @@
[ [
{ {
"inputs": [], "inputs": [
"name": "decimals",
"outputs": [
{ {
"internalType": "uint8", "internalType": "address",
"name": "", "name": "_token",
"type": "uint8" "type": "address"
} }
], ],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "getPrice", "name": "getPrice",
"outputs": [ "outputs": [
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "price", "name": "",
"type": "uint256" "type": "uint256"
} }
], ],

View File

@@ -209,5 +209,31 @@
], ],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "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"
} }
] ]

View File

@@ -532,11 +532,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -611,19 +606,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "baseTokenPriceFeed",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -919,7 +901,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "baseTokenPriceFeed", "name": "lendingPriceSource",
"type": "address" "type": "address"
}, },
{ {
@@ -989,11 +971,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -1067,6 +1044,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "lendingPriceSource",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "owner", "name": "owner",

173
abis/LendingPriceFeed.json Normal file
View File

@@ -0,0 +1,173 @@
[
{
"inputs": [
{
"internalType": "address",
"name": "_ytVault",
"type": "address"
},
{
"internalType": "address",
"name": "_wusdAddress",
"type": "address"
}
],
"stateMutability": "nonpayable",
"type": "constructor"
},
{
"inputs": [],
"name": "InvalidWUSDAddress",
"type": "error"
},
{
"inputs": [],
"name": "InvalidYTVaultAddress",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "owner",
"type": "address"
}
],
"name": "OwnableInvalidOwner",
"type": "error"
},
{
"inputs": [
{
"internalType": "address",
"name": "account",
"type": "address"
}
],
"name": "OwnableUnauthorizedAccount",
"type": "error"
},
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "previousOwner",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "OwnershipTransferred",
"type": "event"
},
{
"inputs": [
{
"internalType": "address",
"name": "_token",
"type": "address"
}
],
"name": "getPrice",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "owner",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "renounceOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_wusdAddress",
"type": "address"
}
],
"name": "setWUSDAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_ytVault",
"type": "address"
}
],
"name": "setYTVault",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "newOwner",
"type": "address"
}
],
"name": "transferOwnership",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [],
"name": "wusdAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "ytVault",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
}
]

View File

@@ -14,11 +14,6 @@
"name": "asset", "name": "asset",
"type": "address" "type": "address"
}, },
{
"internalType": "address",
"name": "priceFeed",
"type": "address"
},
{ {
"internalType": "uint8", "internalType": "uint8",
"name": "decimals", "name": "decimals",
@@ -93,19 +88,6 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "baseTokenPriceFeed",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "borrowIndex", "name": "borrowIndex",
@@ -203,6 +185,19 @@
"stateMutability": "view", "stateMutability": "view",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "lendingPriceSource",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "storeFrontPriceFactor", "name": "storeFrontPriceFactor",

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {

View File

@@ -1,566 +0,0 @@
[
{
"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"
}
]

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -186,12 +191,6 @@
"name": "vault", "name": "vault",
"type": "address" "type": "address"
}, },
{
"indexed": false,
"internalType": "uint256",
"name": "wusdPrice",
"type": "uint256"
},
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
@@ -327,7 +326,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "_wusd", "name": "_usdc",
"type": "address" "type": "address"
}, },
{ {
@@ -337,13 +336,13 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_initialWusdPrice", "name": "_initialYtPrice",
"type": "uint256" "type": "uint256"
}, },
{ {
"internalType": "uint256", "internalType": "address",
"name": "_initialYtPrice", "name": "_usdcPriceFeed",
"type": "uint256" "type": "address"
} }
], ],
"name": "createVault", "name": "createVault",
@@ -381,7 +380,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "_wusd", "name": "_usdc",
"type": "address" "type": "address"
}, },
{ {
@@ -391,13 +390,13 @@
}, },
{ {
"internalType": "uint256[]", "internalType": "uint256[]",
"name": "_initialWusdPrices", "name": "_initialYtPrices",
"type": "uint256[]" "type": "uint256[]"
}, },
{ {
"internalType": "uint256[]", "internalType": "address",
"name": "_initialYtPrices", "name": "_usdcPriceFeed",
"type": "uint256[]" "type": "address"
} }
], ],
"name": "createVaultBatch", "name": "createVaultBatch",
@@ -492,7 +491,7 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "wusdPrice", "name": "usdcPrice",
"type": "uint256" "type": "uint256"
}, },
{ {
@@ -791,11 +790,6 @@
"name": "_vault", "name": "_vault",
"type": "address" "type": "address"
}, },
{
"internalType": "uint256",
"name": "_wusdPrice",
"type": "uint256"
},
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_ytPrice", "name": "_ytPrice",
@@ -814,11 +808,6 @@
"name": "_vaults", "name": "_vaults",
"type": "address[]" "type": "address[]"
}, },
{
"internalType": "uint256[]",
"name": "_wusdPrices",
"type": "uint256[]"
},
{ {
"internalType": "uint256[]", "internalType": "uint256[]",
"name": "_ytPrices", "name": "_ytPrices",

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -139,7 +144,7 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "InsufficientWUSD", "name": "InsufficientUSDC",
"type": "error" "type": "error"
}, },
{ {
@@ -157,6 +162,11 @@
"name": "InvalidBatchSize", "name": "InvalidBatchSize",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "InvalidChainlinkPrice",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "InvalidHardCap", "name": "InvalidHardCap",
@@ -172,6 +182,11 @@
"name": "InvalidPrice", "name": "InvalidPrice",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "InvalidPriceFeed",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "NotInitializing", "name": "NotInitializing",
@@ -305,7 +320,7 @@
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
"name": "totalWusdDistributed", "name": "totalUsdcDistributed",
"type": "uint256" "type": "uint256"
} }
], ],
@@ -324,7 +339,7 @@
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
}, },
{ {
@@ -405,12 +420,6 @@
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "wusdPrice",
"type": "uint256"
},
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
@@ -445,7 +454,7 @@
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
} }
], ],
@@ -527,7 +536,7 @@
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
}, },
{ {
@@ -558,13 +567,26 @@
{ {
"indexed": false, "indexed": false,
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
} }
], ],
"name": "WithdrawRequestProcessed", "name": "WithdrawRequestProcessed",
"type": "event" "type": "event"
}, },
{
"inputs": [],
"name": "CHAINLINK_PRICE_PRECISION",
"outputs": [
{
"internalType": "uint256",
"name": "",
"type": "uint256"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [], "inputs": [],
"name": "PRICE_PRECISION", "name": "PRICE_PRECISION",
@@ -701,7 +723,7 @@
"inputs": [ "inputs": [
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_wusdAmount", "name": "_usdcAmount",
"type": "uint256" "type": "uint256"
} }
], ],
@@ -789,7 +811,7 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
}, },
{ {
@@ -853,7 +875,7 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
}, },
{ {
@@ -930,7 +952,7 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_wusdPrice", "name": "_usdcPrice",
"type": "uint256" "type": "uint256"
}, },
{ {
@@ -997,7 +1019,7 @@
}, },
{ {
"internalType": "address", "internalType": "address",
"name": "_wusd", "name": "_usdc",
"type": "address" "type": "address"
}, },
{ {
@@ -1007,13 +1029,13 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_initialWusdPrice", "name": "_initialYtPrice",
"type": "uint256" "type": "uint256"
}, },
{ {
"internalType": "uint256", "internalType": "address",
"name": "_initialYtPrice", "name": "_usdcPriceFeed",
"type": "uint256" "type": "address"
} }
], ],
"name": "initialize", "name": "initialize",
@@ -1110,7 +1132,7 @@
"inputs": [ "inputs": [
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_wusdAmount", "name": "_usdcAmount",
"type": "uint256" "type": "uint256"
} }
], ],
@@ -1137,7 +1159,7 @@
"outputs": [ "outputs": [
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
} }
], ],
@@ -1347,11 +1369,6 @@
}, },
{ {
"inputs": [ "inputs": [
{
"internalType": "uint256",
"name": "_wusdPrice",
"type": "uint256"
},
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "_ytPrice", "name": "_ytPrice",
@@ -1381,6 +1398,32 @@
"stateMutability": "payable", "stateMutability": "payable",
"type": "function" "type": "function"
}, },
{
"inputs": [],
"name": "usdcAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "usdcDecimals",
"outputs": [
{
"internalType": "uint8",
"name": "",
"type": "uint8"
}
],
"stateMutability": "view",
"type": "function"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -1421,7 +1464,7 @@
}, },
{ {
"internalType": "uint256", "internalType": "uint256",
"name": "wusdAmount", "name": "usdcAmount",
"type": "uint256" "type": "uint256"
}, },
{ {
@@ -1462,32 +1505,6 @@
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "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": [], "inputs": [],
"name": "ytPrice", "name": "ytPrice",

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -157,6 +162,25 @@
"name": "AddLiquidity", "name": "AddLiquidity",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": false,
"internalType": "uint256",
"name": "addition",
"type": "uint256"
},
{
"indexed": false,
"internalType": "uint256",
"name": "deduction",
"type": "uint256"
}
],
"name": "AumAdjustmentChanged",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
@@ -170,6 +194,25 @@
"name": "CooldownDurationSet", "name": "CooldownDurationSet",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oldGov",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newGov",
"type": "address"
}
],
"name": "GovChanged",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -41,6 +46,11 @@
"name": "InvalidAddress", "name": "InvalidAddress",
"type": "error" "type": "error"
}, },
{
"inputs": [],
"name": "InvalidChainlinkPrice",
"type": "error"
},
{ {
"inputs": [], "inputs": [],
"name": "InvalidInitialization", "name": "InvalidInitialization",
@@ -365,7 +375,12 @@
"inputs": [ "inputs": [
{ {
"internalType": "address", "internalType": "address",
"name": "_wusdAddress", "name": "_usdcAddress",
"type": "address"
},
{
"internalType": "address",
"name": "_usdcPriceFeed",
"type": "address" "type": "address"
} }
], ],
@@ -509,11 +524,24 @@
"inputs": [ "inputs": [
{ {
"internalType": "address", "internalType": "address",
"name": "_wusdPriceSource", "name": "_usdcAddress",
"type": "address" "type": "address"
} }
], ],
"name": "setWusdPriceSource", "name": "setUSDCAddress",
"outputs": [],
"stateMutability": "nonpayable",
"type": "function"
},
{
"inputs": [
{
"internalType": "address",
"name": "_usdcPriceFeed",
"type": "address"
}
],
"name": "setUSDCPriceFeed",
"outputs": [], "outputs": [],
"stateMutability": "nonpayable", "stateMutability": "nonpayable",
"type": "function" "type": "function"
@@ -576,20 +604,7 @@
}, },
{ {
"inputs": [], "inputs": [],
"name": "wusdAddress", "name": "usdcAddress",
"outputs": [
{
"internalType": "address",
"name": "",
"type": "address"
}
],
"stateMutability": "view",
"type": "function"
},
{
"inputs": [],
"name": "wusdPriceSource",
"outputs": [ "outputs": [
{ {
"internalType": "address", "internalType": "address",

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {

View File

@@ -1,4 +1,9 @@
[ [
{
"inputs": [],
"stateMutability": "nonpayable",
"type": "constructor"
},
{ {
"inputs": [ "inputs": [
{ {
@@ -207,6 +212,25 @@
"name": "EmergencyModeSet", "name": "EmergencyModeSet",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oldGov",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newGov",
"type": "address"
}
],
"name": "GovChanged",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [
@@ -220,6 +244,25 @@
"name": "Initialized", "name": "Initialized",
"type": "event" "type": "event"
}, },
{
"anonymous": false,
"inputs": [
{
"indexed": true,
"internalType": "address",
"name": "oldManager",
"type": "address"
},
{
"indexed": true,
"internalType": "address",
"name": "newManager",
"type": "address"
}
],
"name": "PoolManagerChanged",
"type": "event"
},
{ {
"anonymous": false, "anonymous": false,
"inputs": [ "inputs": [

File diff suppressed because one or more lines are too long

View File

@@ -1,12 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
/**
* @title IPriceFeed
* @notice 价格预言机接口
*/
interface IPriceFeed {
function getPrice() external view returns (uint256 price);
function decimals() external view returns (uint8);
}

View File

@@ -1,7 +1,6 @@
// SPDX-License-Identifier: MIT // SPDX-License-Identifier: MIT
pragma solidity ^0.8.0; pragma solidity ^0.8.0;
interface IYTToken { interface IYTAssetVault {
function ytPrice() external view returns (uint256); function ytPrice() external view returns (uint256);
function wusdPrice() external view returns (uint256); }
}

View File

@@ -0,0 +1,6 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
interface IYTLendingPriceFeed {
function getPrice(address _token) external view returns (uint256);
}

View File

@@ -11,5 +11,7 @@ interface IYTVault {
function getMinPrice(address _token) external view returns (uint256); function getMinPrice(address _token) external view returns (uint256);
function getSwapFeeBasisPoints(address _tokenIn, address _tokenOut, uint256 _usdyAmount) external view returns (uint256); function getSwapFeeBasisPoints(address _tokenIn, address _tokenOut, uint256 _usdyAmount) external view returns (uint256);
function getRedemptionFeeBasisPoints(address _token, uint256 _usdyAmount) external view returns (uint256); function getRedemptionFeeBasisPoints(address _token, uint256 _usdyAmount) external view returns (uint256);
function ytPrice() external view returns (uint256);
function wusdPrice() external view returns (uint256);
} }

View File

@@ -77,7 +77,7 @@ contract Configurator is
// 设置新配置 // 设置新配置
configuratorParams[lendingProxy].baseToken = newConfiguration.baseToken; configuratorParams[lendingProxy].baseToken = newConfiguration.baseToken;
configuratorParams[lendingProxy].baseTokenPriceFeed = newConfiguration.baseTokenPriceFeed; configuratorParams[lendingProxy].lendingPriceSource = newConfiguration.lendingPriceSource;
configuratorParams[lendingProxy].supplyKink = newConfiguration.supplyKink; configuratorParams[lendingProxy].supplyKink = newConfiguration.supplyKink;
configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeLow = newConfiguration.supplyPerYearInterestRateSlopeLow; configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeLow = newConfiguration.supplyPerYearInterestRateSlopeLow;
configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeHigh = newConfiguration.supplyPerYearInterestRateSlopeHigh; configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeHigh = newConfiguration.supplyPerYearInterestRateSlopeHigh;

View File

@@ -12,7 +12,7 @@ import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import "./LendingStorage.sol"; import "./LendingStorage.sol";
import "./LendingMath.sol"; import "./LendingMath.sol";
import "../interfaces/ILending.sol"; import "../interfaces/ILending.sol";
import "../interfaces/IPriceFeed.sol"; import "../interfaces/IYTLendingPriceFeed.sol";
/** /**
* @title Lending * @title Lending
@@ -45,7 +45,7 @@ contract Lending is
// 设置基础配置 // 设置基础配置
baseToken = config.baseToken; baseToken = config.baseToken;
baseTokenPriceFeed = config.baseTokenPriceFeed; lendingPriceSource = config.lendingPriceSource;
// 常量:一年的秒数 // 常量:一年的秒数
uint64 SECONDS_PER_YEAR = 365 * 24 * 60 * 60; // 31,536,000 uint64 SECONDS_PER_YEAR = 365 * 24 * 60 * 60; // 31,536,000
@@ -327,7 +327,7 @@ contract Lending is
if (oldBalance >= 0) revert NotLiquidatable(); if (oldBalance >= 0) revert NotLiquidatable();
// 计算所有抵押品的总价值(按 liquidationFactor 折扣) // 计算所有抵押品的总价值(按 liquidationFactor 折扣)
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice(); uint256 basePrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(baseToken);
uint256 totalCollateralValue = 0; uint256 totalCollateralValue = 0;
for (uint i = 0; i < assetList.length; i++) { for (uint i = 0; i < assetList.length; i++) {
@@ -336,7 +336,7 @@ contract Lending is
if (collateralAmount > 0) { if (collateralAmount > 0) {
AssetConfig memory assetConfig = assetConfigs[asset]; AssetConfig memory assetConfig = assetConfigs[asset];
uint256 assetPrice = IPriceFeed(assetConfig.priceFeed).getPrice(); uint256 assetPrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(asset);
// 计算抵押品价值USD8位精度- 用于事件记录 // 计算抵押品价值USD8位精度- 用于事件记录
uint256 assetScale = 10 ** assetConfig.decimals; uint256 assetScale = 10 ** assetConfig.decimals;
@@ -454,24 +454,44 @@ contract Lending is
/** /**
* @notice 计算支付指定baseAmount可购买的抵押品数量 * @notice 计算支付指定baseAmount可购买的抵押品数量
* @dev 重新设计以避免在 1e30 价格精度下溢出
*/ */
function quoteCollateral(address asset, uint256 baseAmount) public view override returns (uint256) { function quoteCollateral(address asset, uint256 baseAmount) public view override returns (uint256) {
AssetConfig memory assetConfig = assetConfigs[asset]; AssetConfig memory assetConfig = assetConfigs[asset];
uint256 assetPrice = IPriceFeed(assetConfig.priceFeed).getPrice(); uint256 assetPrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(asset);
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice(); uint256 basePrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(baseToken);
uint256 FACTOR_SCALE = 1e18; uint256 FACTOR_SCALE = 1e18;
uint256 baseScale = 10 ** uint256(IERC20Metadata(baseToken).decimals()); uint256 baseScale = 10 ** uint256(IERC20Metadata(baseToken).decimals());
uint256 assetScale = 10 ** uint256(assetConfig.decimals); uint256 assetScale = 10 ** uint256(assetConfig.decimals);
// 折扣因子 // 计算折扣因子
uint256 discountFactor = (storeFrontPriceFactor * (FACTOR_SCALE - assetConfig.liquidationFactor)) / FACTOR_SCALE; uint256 discountFactor = (storeFrontPriceFactor * (FACTOR_SCALE - assetConfig.liquidationFactor)) / FACTOR_SCALE;
// 分子: basePrice * baseAmount * assetScale * FACTOR_SCALE // 计算折扣后的资产价格 (保持 1e30 精度)
// 分母: assetPrice * (FACTOR_SCALE - discountFactor) * baseScale uint256 effectiveAssetPrice = (assetPrice * (FACTOR_SCALE - discountFactor)) / FACTOR_SCALE;
return (basePrice * baseAmount * assetScale * FACTOR_SCALE) /
(assetPrice * (FACTOR_SCALE - discountFactor) * baseScale); // 为了避免溢出,我们需要重新排列计算:
// result = (basePrice * baseAmount * assetScale) / (effectiveAssetPrice * baseScale)
//
// 由于所有价格都是 1e30 精度,我们可以先约简价格:
// priceRatio = basePrice / effectiveAssetPrice (保持精度)
// result = (baseAmount * priceRatio * assetScale) / (1e30 * baseScale)
//
// 但为了避免精度损失,我们分步计算:
// step1 = baseAmount * assetScale / baseScale (token amount conversion)
// step2 = step1 * basePrice / effectiveAssetPrice (price conversion)
// 如果 baseScale 和 assetScale 相同(都是18),可以简化
if (baseScale == assetScale) {
// result = baseAmount * basePrice / effectiveAssetPrice
return (baseAmount * basePrice) / effectiveAssetPrice;
} else {
// 一般情况:分步计算避免溢出
uint256 adjustedAmount = (baseAmount * assetScale) / baseScale;
return (adjustedAmount * basePrice) / effectiveAssetPrice;
}
} }
/** /**
@@ -486,7 +506,7 @@ contract Lending is
uint256 debt = uint256(-balance); uint256 debt = uint256(-balance);
// 将 debt 转换为美元价值(使用 baseToken 价格) // 将 debt 转换为美元价值(使用 baseToken 价格)
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice(); uint256 basePrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(baseToken);
uint256 baseDecimals = IERC20Metadata(baseToken).decimals(); uint256 baseDecimals = IERC20Metadata(baseToken).decimals();
uint256 debtValue = (debt * basePrice) / (10 ** baseDecimals); uint256 debtValue = (debt * basePrice) / (10 ** baseDecimals);
@@ -508,7 +528,7 @@ contract Lending is
uint256 amount = userCollateral[account][asset]; uint256 amount = userCollateral[account][asset];
if (amount > 0) { if (amount > 0) {
AssetConfig memory config = assetConfigs[asset]; AssetConfig memory config = assetConfigs[asset];
uint256 price = IPriceFeed(config.priceFeed).getPrice(); uint256 price = IYTLendingPriceFeed(lendingPriceSource).getPrice(asset);
uint256 value = LendingMath.getCollateralValue(amount, price, config.decimals); uint256 value = LendingMath.getCollateralValue(amount, price, config.decimals);
totalValue += (value * config.borrowCollateralFactor) / 1e18; totalValue += (value * config.borrowCollateralFactor) / 1e18;
} }
@@ -553,7 +573,7 @@ contract Lending is
uint256 debt = uint256(-balance); uint256 debt = uint256(-balance);
// 将 debt 转换为美元价值(使用 baseToken 价格和 price feed 精度) // 将 debt 转换为美元价值(使用 baseToken 价格和 price feed 精度)
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice(); uint256 basePrice = IYTLendingPriceFeed(lendingPriceSource).getPrice(baseToken);
uint256 baseDecimals = IERC20Metadata(baseToken).decimals(); uint256 baseDecimals = IERC20Metadata(baseToken).decimals();
uint256 debtValue = (debt * basePrice) / (10 ** baseDecimals); uint256 debtValue = (debt * basePrice) / (10 ** baseDecimals);
@@ -564,7 +584,7 @@ contract Lending is
uint256 amount = userCollateral[account][asset]; uint256 amount = userCollateral[account][asset];
if (amount > 0) { if (amount > 0) {
AssetConfig memory config = assetConfigs[asset]; AssetConfig memory config = assetConfigs[asset];
uint256 price = IPriceFeed(config.priceFeed).getPrice(); uint256 price = IYTLendingPriceFeed(lendingPriceSource).getPrice(asset);
uint256 value = LendingMath.getCollateralValue(amount, price, config.decimals); uint256 value = LendingMath.getCollateralValue(amount, price, config.decimals);
collateralValue += (value * config.liquidateCollateralFactor) / 1e18; collateralValue += (value * config.liquidateCollateralFactor) / 1e18;
} }

View File

@@ -8,7 +8,6 @@ pragma solidity ^0.8.0;
contract LendingConfiguration { contract LendingConfiguration {
struct AssetConfig { struct AssetConfig {
address asset; // 资产地址 address asset; // 资产地址
address priceFeed; // 价格预言机地址
uint8 decimals; // 小数位数 uint8 decimals; // 小数位数
uint64 borrowCollateralFactor; // 借款抵押率 uint64 borrowCollateralFactor; // 借款抵押率
uint64 liquidateCollateralFactor; // 清算抵押率 uint64 liquidateCollateralFactor; // 清算抵押率
@@ -18,7 +17,7 @@ contract LendingConfiguration {
struct Configuration { struct Configuration {
address baseToken; // 基础资产 address baseToken; // 基础资产
address baseTokenPriceFeed; // 基础资产价格预言机 address lendingPriceSource; // 借贷价格源
// 利率模型参数 // 利率模型参数
uint64 supplyKink; // 供应拐点利用率 uint64 supplyKink; // 供应拐点利用率

View File

@@ -7,7 +7,6 @@ pragma solidity ^0.8.0;
*/ */
library LendingMath { library LendingMath {
uint256 internal constant FACTOR_SCALE = 1e18; uint256 internal constant FACTOR_SCALE = 1e18;
uint256 internal constant PRICE_SCALE = 1e8;
uint256 internal constant SECONDS_PER_YEAR = 365 * 24 * 60 * 60; uint256 internal constant SECONDS_PER_YEAR = 365 * 24 * 60 * 60;
/** /**

View File

@@ -0,0 +1,39 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "../interfaces/IYTVault.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
contract LendingPriceFeed is Ownable {
address public ytVault;
address public wusdAddress;
error InvalidYTVaultAddress();
error InvalidWUSDAddress();
constructor(address _ytVault, address _wusdAddress) Ownable(msg.sender) {
if (_ytVault == address(0)) revert InvalidYTVaultAddress();
if (_wusdAddress == address(0)) revert InvalidWUSDAddress();
ytVault = _ytVault;
wusdAddress = _wusdAddress;
}
function setYTVault(address _ytVault) external onlyOwner {
if (_ytVault == address(0)) revert InvalidYTVaultAddress();
ytVault = _ytVault;
}
function setWUSDAddress(address _wusdAddress) external onlyOwner {
if (_wusdAddress == address(0)) revert InvalidWUSDAddress();
wusdAddress = _wusdAddress;
}
function getPrice(address _token) external view returns (uint256) {
if (_token == wusdAddress) {
return IYTVault(ytVault).wusdPrice();
} else {
return IYTVault(_token).ytPrice();
}
}
}

View File

@@ -11,7 +11,7 @@ abstract contract LendingStorage is LendingConfiguration {
// 市场配置 // 市场配置
address public baseToken; address public baseToken;
address public baseTokenPriceFeed; address public lendingPriceSource;
// 利率参数(每秒利率,已从年化利率转换) // 利率参数(每秒利率,已从年化利率转换)
uint64 public supplyKink; uint64 public supplyKink;

View File

@@ -257,7 +257,7 @@ contract YTPoolManager is Initializable, UUPSUpgradeable, ReentrancyGuardUpgrade
function getAumInUsdy(bool _maximise) public view returns (uint256) { function getAumInUsdy(bool _maximise) public view returns (uint256) {
uint256 aum = IYTVault(ytVault).getPoolValue(_maximise); uint256 aum = IYTVault(ytVault).getPoolValue(_maximise);
aum += aumAddition; aum += aumAddition; // aumAddition是协议额外增加的AUM用来“预留风险缓冲 / 扣除潜在负债”
if (aum > aumDeduction) { if (aum > aumDeduction) {
aum -= aumDeduction; aum -= aumDeduction;
} else { } else {

View File

@@ -3,7 +3,8 @@ pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "../../interfaces/IYTToken.sol"; import "../../interfaces/IYTAssetVault.sol";
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
/** /**
* @title YTPriceFeed * @title YTPriceFeed
@@ -22,6 +23,7 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
error PriceChangeTooLarge(); error PriceChangeTooLarge();
error SpreadTooHigh(); error SpreadTooHigh();
error InvalidAddress(); error InvalidAddress();
error InvalidChainlinkPrice();
address public gov; address public gov;
@@ -29,14 +31,13 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
uint256 public constant BASIS_POINTS_DIVISOR = 10000; uint256 public constant BASIS_POINTS_DIVISOR = 10000;
uint256 public constant MAX_SPREAD_BASIS_POINTS = 200; // 最大2%价差 uint256 public constant MAX_SPREAD_BASIS_POINTS = 200; // 最大2%价差
// WUSD固定价格 address public usdcAddress;
address public wusdAddress;
// WUSD价格来源
address public wusdPriceSource;
// 价格保护参数 // 价格保护参数
uint256 public maxPriceChangeBps; // 5% 最大价格变动 uint256 public maxPriceChangeBps; // 5% 最大价格变动
/// @notice USDC价格Feed
AggregatorV3Interface internal usdcPriceFeed;
// 价差配置(每个代币可以有不同的价差) // 价差配置(每个代币可以有不同的价差)
mapping(address => uint256) public spreadBasisPoints; mapping(address => uint256) public spreadBasisPoints;
@@ -64,13 +65,31 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
/** /**
* @notice 初始化合约 * @notice 初始化合约
*/ */
function initialize(address _wusdAddress) external initializer { function initialize(address _usdcAddress, address _usdcPriceFeed) external initializer {
__UUPSUpgradeable_init(); __UUPSUpgradeable_init();
if (_wusdAddress == address(0)) revert InvalidAddress(); if (_usdcAddress == address(0)) revert InvalidAddress();
wusdAddress = _wusdAddress; usdcAddress = _usdcAddress;
usdcPriceFeed = AggregatorV3Interface(_usdcPriceFeed);
gov = msg.sender; gov = msg.sender;
maxPriceChangeBps = 500; // 5% 最大价格变动 maxPriceChangeBps = 500; // 5% 最大价格变动
} }
/**
* @notice 设置USDC地址
* @param _usdcAddress USDC地址
*/
function setUSDCAddress(address _usdcAddress) external onlyGov {
if (_usdcAddress == address(0)) revert InvalidAddress();
usdcAddress = _usdcAddress;
}
/**
* @notice 设置USDC价格Feed
* @param _usdcPriceFeed USDC价格Feed地址
*/
function setUSDCPriceFeed(address _usdcPriceFeed) external onlyGov {
usdcPriceFeed = AggregatorV3Interface(_usdcPriceFeed);
}
/** /**
* @notice 授权升级仅gov可调用 * @notice 授权升级仅gov可调用
@@ -78,14 +97,6 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
*/ */
function _authorizeUpgrade(address newImplementation) internal override onlyGov {} function _authorizeUpgrade(address newImplementation) internal override onlyGov {}
/**
* @notice 设置WUSD价格来源YTAssetVault地址
* @param _wusdPriceSource YTAssetVault合约地址
*/
function setWusdPriceSource(address _wusdPriceSource) external onlyGov {
wusdPriceSource = _wusdPriceSource;
}
/** /**
* @notice 设置keeper权限 * @notice 设置keeper权限
* @param _keeper keeper地址 * @param _keeper keeper地址
@@ -132,6 +143,30 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
emit SpreadUpdate(_tokens[i], _spreadBasisPoints[i]); emit SpreadUpdate(_tokens[i], _spreadBasisPoints[i]);
} }
} }
/**
* @notice 更新并缓存代币价格keeper调用
* @param _token 代币地址
* @return 更新后的价格
*/
function updatePrice(address _token) external onlyKeeper returns (uint256) {
if (_token == usdcAddress) {
return _getUSDCPrice();
}
uint256 oldPrice = lastPrice[_token];
uint256 newPrice = _getRawPrice(_token);
// 价格波动检查
_validatePriceChange(_token, newPrice);
// 更新缓存价格
lastPrice[_token] = newPrice;
emit PriceUpdate(_token, oldPrice, newPrice, block.timestamp);
return newPrice;
}
/** /**
* @notice 强制更新价格(紧急情况) * @notice 强制更新价格(紧急情况)
@@ -159,8 +194,8 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
* - swap时tokenOut_maximise=true高估输出 * - swap时tokenOut_maximise=true高估输出
*/ */
function getPrice(address _token, bool _maximise) external view returns (uint256) { function getPrice(address _token, bool _maximise) external view returns (uint256) {
if (_token == wusdAddress) { if (_token == usdcAddress) {
return _getWUSDPrice(); return _getUSDCPrice();
} }
uint256 basePrice = _getRawPrice(_token); uint256 basePrice = _getRawPrice(_token);
@@ -172,47 +207,31 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
return _applySpread(_token, basePrice, _maximise); return _applySpread(_token, basePrice, _maximise);
} }
/**
* @notice 更新价格并返回由keeper调用
* @param _token 代币地址
* @return 新价格
*/
function updatePrice(address _token) external onlyKeeper returns (uint256) {
if (_token == wusdAddress) {
return _getWUSDPrice();
}
uint256 oldPrice = lastPrice[_token];
uint256 newPrice = _getRawPrice(_token);
// 价格波动检查
_validatePriceChange(_token, newPrice);
lastPrice[_token] = newPrice;
emit PriceUpdate(_token, oldPrice, newPrice, block.timestamp);
return newPrice;
}
/** /**
* @notice 直接读取YT代币的ytPrice变量 * @notice 直接读取YT代币的ytPrice变量
*/ */
function _getRawPrice(address _token) private view returns (uint256) { function _getRawPrice(address _token) private view returns (uint256) {
return IYTToken(_token).ytPrice(); return IYTAssetVault(_token).ytPrice();
} }
/** /**
* @notice 从配置的YTAssetVault读取wusdPrice * @notice 获取并验证USDC价格从Chainlink
* @dev 如果未设置wusdPriceSource返回固定价格1.0 * @return 返回uint256格式的USDC价格精度为1e30
*/ */
function _getWUSDPrice() private view returns (uint256) { function _getUSDCPrice() internal view returns (uint256) {
if (wusdPriceSource == address(0)) { (
return PRICE_PRECISION; // 默认1.0 /* uint80 roundId */,
} int256 price,
return IYTToken(wusdPriceSource).wusdPrice(); /* uint256 startedAt */,
/* uint256 updatedAt */,
/* uint80 answeredInRound */
) = usdcPriceFeed.latestRoundData();
if (price <= 0) revert InvalidChainlinkPrice();
return uint256(price) * 1e22; // 1e22 = 10^(30-8)
} }
/** /**
* @notice 应用价差 * @notice 应用价差
* @param _token 代币地址 * @param _token 代币地址
@@ -269,12 +288,12 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
uint256 minPrice, uint256 minPrice,
uint256 spread uint256 spread
) { ) {
if (_token == wusdAddress) { if (_token == usdcAddress) {
uint256 wusdPrice = _getWUSDPrice(); uint256 usdcPrice = _getUSDCPrice();
currentPrice = wusdPrice; currentPrice = usdcPrice;
cachedPrice = wusdPrice; cachedPrice = usdcPrice;
maxPrice = wusdPrice; maxPrice = usdcPrice;
minPrice = wusdPrice; minPrice = usdcPrice;
spread = 0; spread = 0;
} else { } else {
currentPrice = _getRawPrice(_token); currentPrice = _getRawPrice(_token);
@@ -289,9 +308,9 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
* @notice 获取最大价格(上浮价差) * @notice 获取最大价格(上浮价差)
*/ */
function getMaxPrice(address _token) external view returns (uint256) { function getMaxPrice(address _token) external view returns (uint256) {
if (_token == wusdAddress) { if (_token == usdcAddress) {
// WUSD通常不需要价差直接返回原价格 // USDC通常不需要价差,直接返回原价格
return _getWUSDPrice(); return _getUSDCPrice();
} }
uint256 basePrice = _getRawPrice(_token); uint256 basePrice = _getRawPrice(_token);
_validatePriceChange(_token, basePrice); _validatePriceChange(_token, basePrice);
@@ -302,9 +321,9 @@ contract YTPriceFeed is Initializable, UUPSUpgradeable {
* @notice 获取最小价格(下压价差) * @notice 获取最小价格(下压价差)
*/ */
function getMinPrice(address _token) external view returns (uint256) { function getMinPrice(address _token) external view returns (uint256) {
if (_token == wusdAddress) { if (_token == usdcAddress) {
// WUSD通常不需要价差直接返回原价格 // USDC通常不需要价差,直接返回原价格
return _getWUSDPrice(); return _getUSDCPrice();
} }
uint256 basePrice = _getRawPrice(_token); uint256 basePrice = _getRawPrice(_token);
_validatePriceChange(_token, basePrice); _validatePriceChange(_token, basePrice);

View File

@@ -72,7 +72,6 @@ contract YTRewardRouter is Initializable, UUPSUpgradeable, ReentrancyGuardUpgrad
gov = msg.sender; gov = msg.sender;
usdy = _usdy; usdy = _usdy;
ytLP = _ytLP; ytLP = _ytLP;
ytPoolManager = _ytPoolManager; ytPoolManager = _ytPoolManager;
@@ -102,7 +101,7 @@ contract YTRewardRouter is Initializable, UUPSUpgradeable, ReentrancyGuardUpgrad
/** /**
* @notice 添加流动性 * @notice 添加流动性
* @param _token YT代币或WUSD地址 * @param _token YT代币或USDC地址
* @param _amount 代币数量 * @param _amount 代币数量
* @param _minUsdy 最小USDY数量 * @param _minUsdy 最小USDY数量
* @param _minYtLP 最小ytLP数量 * @param _minYtLP 最小ytLP数量

View File

@@ -390,7 +390,7 @@ contract YTVault is Initializable, UUPSUpgradeable, ReentrancyGuardUpgradeable {
if (amountOutAfterFees == 0) revert InvalidAmount(); if (amountOutAfterFees == 0) revert InvalidAmount();
if (poolAmounts[_tokenOut] < amountOutAfterFees) revert InsufficientPool(); if (poolAmounts[_tokenOut] < amountOutAfterFees) revert InsufficientPool();
// 全局滑点保护 // 全局滑点保护10%
_validateSwapSlippage(amountIn, amountOutAfterFees, priceIn, priceOut); _validateSwapSlippage(amountIn, amountOutAfterFees, priceIn, priceOut);
_increasePoolAmount(_tokenIn, amountIn); _increasePoolAmount(_tokenIn, amountIn);
@@ -509,7 +509,7 @@ contract YTVault is Initializable, UUPSUpgradeable, ReentrancyGuardUpgradeable {
address _tokenOut, address _tokenOut,
uint256 _usdyAmount uint256 _usdyAmount
) private view returns (uint256) { ) private view returns (uint256) {
// 稳定币交换是指两个代币都是稳定币(如 WUSD <-> USDC // 稳定币交换是指两个代币都是稳定币(如 USDC <-> USDT
bool isStableSwap = stableTokens[_tokenIn] && stableTokens[_tokenOut]; bool isStableSwap = stableTokens[_tokenIn] && stableTokens[_tokenOut];
uint256 baseBps = isStableSwap ? stableSwapFeeBasisPoints : swapFeeBasisPoints; uint256 baseBps = isStableSwap ? stableSwapFeeBasisPoints : swapFeeBasisPoints;
uint256 taxBps = isStableSwap ? stableTaxBasisPoints : taxBasisPoints; uint256 taxBps = isStableSwap ? stableTaxBasisPoints : taxBasisPoints;

View File

@@ -1,59 +0,0 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
/**
* @title WUSD
* @notice Wrapped USD - 简单的ERC20代币
*/
contract WUSD is Initializable, ERC20Upgradeable, UUPSUpgradeable, OwnableUpgradeable {
/// @custom:oz-upgrades-unsafe-allow constructor
constructor() {
_disableInitializers();
}
/**
* @notice 初始化合约
* @param _name 代币名称
* @param _symbol 代币符号
*/
function initialize(string memory _name, string memory _symbol) external initializer {
__ERC20_init(_name, _symbol);
__UUPSUpgradeable_init();
__Ownable_init(msg.sender);
}
/**
* @notice 授权升级仅owner可调用
* @param newImplementation 新实现合约地址
*/
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
/**
* @notice 铸造代币
* @param _to 接收地址
* @param _amount 铸造数量
*/
function mint(address _to, uint256 _amount) external onlyOwner {
_mint(_to, _amount);
}
/**
* @notice 销毁代币
* @param _from 销毁地址
* @param _amount 销毁数量
*/
function burn(address _from, uint256 _amount) external onlyOwner {
_burn(_from, _amount);
}
/**
* @dev 预留存储空间,用于未来升级时添加新的状态变量
*/
uint256[50] private __gap;
}

View File

@@ -46,7 +46,7 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
event VaultImplementationUpdated(address indexed newImplementation); event VaultImplementationUpdated(address indexed newImplementation);
event DefaultHardCapSet(uint256 newDefaultHardCap); event DefaultHardCapSet(uint256 newDefaultHardCap);
event HardCapSet(address indexed vault, uint256 newHardCap); event HardCapSet(address indexed vault, uint256 newHardCap);
event PricesUpdated(address indexed vault, uint256 wusdPrice, uint256 ytPrice); event PricesUpdated(address indexed vault, uint256 ytPrice);
event NextRedemptionTimeSet(address indexed vault, uint256 redemptionTime); event NextRedemptionTimeSet(address indexed vault, uint256 redemptionTime);
/** /**
@@ -98,10 +98,10 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
* @param _symbol YT代币符号 * @param _symbol YT代币符号
* @param _manager 管理员地址 * @param _manager 管理员地址
* @param _hardCap 硬顶限制0表示使用默认值 * @param _hardCap 硬顶限制0表示使用默认值
* @param _wusd WUSD代币地址传0使用默认地址 * @param _usdc USDC代币地址传0使用默认地址
* @param _redemptionTime 赎回时间Unix时间戳 * @param _redemptionTime 赎回时间Unix时间戳
* @param _initialWusdPrice 初始WUSD价格精度1e30传0则使用默认值1.0
* @param _initialYtPrice 初始YT价格精度1e30传0则使用默认值1.0 * @param _initialYtPrice 初始YT价格精度1e30传0则使用默认值1.0
* @param _usdcPriceFeed Chainlink USDC价格Feed地址
* @return vault 新创建的vault地址 * @return vault 新创建的vault地址
*/ */
function createVault( function createVault(
@@ -109,10 +109,10 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
string memory _symbol, string memory _symbol,
address _manager, address _manager,
uint256 _hardCap, uint256 _hardCap,
address _wusd, address _usdc,
uint256 _redemptionTime, uint256 _redemptionTime,
uint256 _initialWusdPrice, uint256 _initialYtPrice,
uint256 _initialYtPrice address _usdcPriceFeed
) external onlyOwner returns (address vault) { ) external onlyOwner returns (address vault) {
if (_manager == address(0)) revert InvalidAddress(); if (_manager == address(0)) revert InvalidAddress();
@@ -126,10 +126,10 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
_symbol, _symbol,
_manager, _manager,
actualHardCap, actualHardCap,
_wusd, _usdc,
_redemptionTime, _redemptionTime,
_initialWusdPrice, _initialYtPrice,
_initialYtPrice _usdcPriceFeed
); );
// 部署代理合约 // 部署代理合约
@@ -155,10 +155,10 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
* @param _symbols YT代币符号数组 * @param _symbols YT代币符号数组
* @param _managers 管理员地址数组 * @param _managers 管理员地址数组
* @param _hardCaps 硬顶数组 * @param _hardCaps 硬顶数组
* @param _wusd WUSD代币地址传0使用默认地址 * @param _usdc USDC代币地址传0使用默认地址
* @param _redemptionTimes 赎回时间数组Unix时间戳 * @param _redemptionTimes 赎回时间数组Unix时间戳
* @param _initialWusdPrices 初始WUSD价格数组精度1e30
* @param _initialYtPrices 初始YT价格数组精度1e30 * @param _initialYtPrices 初始YT价格数组精度1e30
* @param _usdcPriceFeed Chainlink USDC价格Feed地址
* @return vaults 创建的vault地址数组 * @return vaults 创建的vault地址数组
*/ */
function createVaultBatch( function createVaultBatch(
@@ -166,17 +166,16 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
string[] memory _symbols, string[] memory _symbols,
address[] memory _managers, address[] memory _managers,
uint256[] memory _hardCaps, uint256[] memory _hardCaps,
address _wusd, address _usdc,
uint256[] memory _redemptionTimes, uint256[] memory _redemptionTimes,
uint256[] memory _initialWusdPrices, uint256[] memory _initialYtPrices,
uint256[] memory _initialYtPrices address _usdcPriceFeed
) external returns (address[] memory vaults) { ) external returns (address[] memory vaults) {
require( require(
_names.length == _symbols.length && _names.length == _symbols.length &&
_names.length == _managers.length && _names.length == _managers.length &&
_names.length == _hardCaps.length && _names.length == _hardCaps.length &&
_names.length == _redemptionTimes.length && _names.length == _redemptionTimes.length &&
_names.length == _initialWusdPrices.length &&
_names.length == _initialYtPrices.length, _names.length == _initialYtPrices.length,
"Length mismatch" "Length mismatch"
); );
@@ -189,10 +188,10 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
_symbols[i], _symbols[i],
_managers[i], _managers[i],
_hardCaps[i], _hardCaps[i],
_wusd, _usdc,
_redemptionTimes[i], _redemptionTimes[i],
_initialWusdPrices[i], _initialYtPrices[i],
_initialYtPrices[i] _usdcPriceFeed
); );
} }
} }
@@ -312,41 +311,33 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
/** /**
* @notice 更新vault价格 * @notice 更新vault价格
* @param _vault vault地址 * @param _vault vault地址
* @param _wusdPrice WUSD价格精度1e30
* @param _ytPrice YT价格精度1e30 * @param _ytPrice YT价格精度1e30
*/ */
function updateVaultPrices( function updateVaultPrices(
address _vault, address _vault,
uint256 _wusdPrice,
uint256 _ytPrice uint256 _ytPrice
) external onlyOwner { ) external onlyOwner {
if (!isVault[_vault]) revert VaultNotExists(); if (!isVault[_vault]) revert VaultNotExists();
YTAssetVault(_vault).updatePrices(_wusdPrice, _ytPrice); YTAssetVault(_vault).updatePrices(_ytPrice);
emit PricesUpdated(_vault, _wusdPrice, _ytPrice); emit PricesUpdated(_vault, _ytPrice);
} }
/** /**
* @notice 批量更新价格 * @notice 批量更新价格
* @param _vaults vault地址数组 * @param _vaults vault地址数组
* @param _wusdPrices WUSD价格数组精度1e30
* @param _ytPrices YT价格数组精度1e30 * @param _ytPrices YT价格数组精度1e30
*/ */
function updateVaultPricesBatch( function updateVaultPricesBatch(
address[] memory _vaults, address[] memory _vaults,
uint256[] memory _wusdPrices,
uint256[] memory _ytPrices uint256[] memory _ytPrices
) external onlyOwner { ) external onlyOwner {
require( require(_vaults.length == _ytPrices.length, "Length mismatch");
_vaults.length == _wusdPrices.length &&
_vaults.length == _ytPrices.length,
"Length mismatch"
);
for (uint256 i = 0; i < _vaults.length; i++) { for (uint256 i = 0; i < _vaults.length; i++) {
if (!isVault[_vaults[i]]) revert VaultNotExists(); if (!isVault[_vaults[i]]) revert VaultNotExists();
YTAssetVault(_vaults[i]).updatePrices(_wusdPrices[i], _ytPrices[i]); YTAssetVault(_vaults[i]).updatePrices(_ytPrices[i]);
emit PricesUpdated(_vaults[i], _wusdPrices[i], _ytPrices[i]); emit PricesUpdated(_vaults[i], _ytPrices[i]);
} }
} }
@@ -422,7 +413,7 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
uint256 managedAssets, uint256 managedAssets,
uint256 totalSupply, uint256 totalSupply,
uint256 hardCap, uint256 hardCap,
uint256 wusdPrice, uint256 usdcPrice,
uint256 ytPrice, uint256 ytPrice,
uint256 nextRedemptionTime uint256 nextRedemptionTime
) { ) {
@@ -434,7 +425,7 @@ contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
managedAssets, managedAssets,
totalSupply, totalSupply,
hardCap, hardCap,
wusdPrice, usdcPrice,
ytPrice, ytPrice,
nextRedemptionTime nextRedemptionTime
) = YTAssetVault(_vault).getVaultInfo(); ) = YTAssetVault(_vault).getVaultInfo();

View File

@@ -7,11 +7,13 @@ import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol"; import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
import "@openzeppelin/contracts/token/ERC20/IERC20.sol"; import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
import "@openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol";
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol"; import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
import {AggregatorV3Interface} from "@chainlink/contracts/src/v0.8/shared/interfaces/AggregatorV3Interface.sol";
/** /**
* @title YTAssetVault * @title YTAssetVault
* @notice 基于价格的资产金库,用户根据WUSD和YT代币价格进行兑换 * @notice 基于价格的资产金库用户根据USDC和YT代币价格进行兑换
* @dev UUPS可升级合约YT是份额代币 * @dev UUPS可升级合约YT是份额代币
*/ */
contract YTAssetVault is contract YTAssetVault is
@@ -33,12 +35,14 @@ contract YTAssetVault is
error InvalidAmount(); error InvalidAmount();
error InvalidHardCap(); error InvalidHardCap();
error InvalidPrice(); error InvalidPrice();
error InsufficientWUSD(); error InsufficientUSDC();
error InsufficientYTA(); error InsufficientYTA();
error StillInLockPeriod(); error StillInLockPeriod();
error RequestNotFound(); error RequestNotFound();
error RequestAlreadyProcessed(); error RequestAlreadyProcessed();
error InvalidBatchSize(); error InvalidBatchSize();
error InvalidPriceFeed();
error InvalidChainlinkPrice();
/// @notice 工厂合约地址 /// @notice 工厂合约地址
address public factory; address public factory;
@@ -49,14 +53,14 @@ contract YTAssetVault is
/// @notice YT代币硬顶最大可铸造的YT数量 /// @notice YT代币硬顶最大可铸造的YT数量
uint256 public hardCap; uint256 public hardCap;
/// @notice 已提取用于管理的WUSD数量 /// @notice 已提取用于管理的USDC数量
uint256 public managedAssets; uint256 public managedAssets;
/// @notice WUSD代币地址 /// @notice USDC代币地址
address public wusdAddress; address public usdcAddress;
/// @notice WUSD价格精度1e30 /// @notice USDC代币精度从代币合约读取
uint256 public wusdPrice; uint8 public usdcDecimals;
/// @notice YT价格精度1e30 /// @notice YT价格精度1e30
uint256 public ytPrice; uint256 public ytPrice;
@@ -64,14 +68,20 @@ contract YTAssetVault is
/// @notice 价格精度 /// @notice 价格精度
uint256 public constant PRICE_PRECISION = 1e30; uint256 public constant PRICE_PRECISION = 1e30;
/// @notice Chainlink价格精度
uint256 public constant CHAINLINK_PRICE_PRECISION = 1e8;
/// @notice 下一个赎回开放时间(所有用户统一) /// @notice 下一个赎回开放时间(所有用户统一)
uint256 public nextRedemptionTime; uint256 public nextRedemptionTime;
/// @notice USDC价格Feed
AggregatorV3Interface internal usdcPriceFeed;
/// @notice 提现请求结构体 /// @notice 提现请求结构体
struct WithdrawRequest { struct WithdrawRequest {
address user; // 用户地址 address user; // 用户地址
uint256 ytAmount; // YT数量 uint256 ytAmount; // YT数量
uint256 wusdAmount; // 应得WUSD数量 uint256 usdcAmount; // 应得USDC数量
uint256 requestTime; // 请求时间 uint256 requestTime; // 请求时间
uint256 queueIndex; // 队列位置 uint256 queueIndex; // 队列位置
bool processed; // 是否已处理 bool processed; // 是否已处理
@@ -96,13 +106,13 @@ contract YTAssetVault is
event ManagerSet(address indexed newManager); event ManagerSet(address indexed newManager);
event AssetsWithdrawn(address indexed to, uint256 amount); event AssetsWithdrawn(address indexed to, uint256 amount);
event AssetsDeposited(uint256 amount); event AssetsDeposited(uint256 amount);
event PriceUpdated(uint256 wusdPrice, uint256 ytPrice, uint256 timestamp); event PriceUpdated(uint256 ytPrice, uint256 timestamp);
event Buy(address indexed user, uint256 wusdAmount, uint256 ytAmount); event Buy(address indexed user, uint256 usdcAmount, uint256 ytAmount);
event Sell(address indexed user, uint256 ytAmount, uint256 wusdAmount); event Sell(address indexed user, uint256 ytAmount, uint256 usdcAmount);
event NextRedemptionTimeSet(uint256 newRedemptionTime); event NextRedemptionTimeSet(uint256 newRedemptionTime);
event WithdrawRequestCreated(uint256 indexed requestId, address indexed user, uint256 ytAmount, uint256 wusdAmount, uint256 queueIndex); event WithdrawRequestCreated(uint256 indexed requestId, address indexed user, uint256 ytAmount, uint256 usdcAmount, uint256 queueIndex);
event WithdrawRequestProcessed(uint256 indexed requestId, address indexed user, uint256 wusdAmount); event WithdrawRequestProcessed(uint256 indexed requestId, address indexed user, uint256 usdcAmount);
event BatchProcessed(uint256 startIndex, uint256 endIndex, uint256 processedCount, uint256 totalWusdDistributed); event BatchProcessed(uint256 startIndex, uint256 endIndex, uint256 processedCount, uint256 totalUsdcDistributed);
modifier onlyFactory() { modifier onlyFactory() {
if (msg.sender != factory) revert Forbidden(); if (msg.sender != factory) revert Forbidden();
@@ -120,38 +130,37 @@ contract YTAssetVault is
* @param _symbol YT代币符号 * @param _symbol YT代币符号
* @param _manager 管理员地址 * @param _manager 管理员地址
* @param _hardCap 硬顶限制 * @param _hardCap 硬顶限制
* @param _wusd WUSD代币地址可选传0则使用默认地址 * @param _usdc USDC代币地址可选传0则使用默认地址
* @param _redemptionTime 赎回时间Unix时间戳 * @param _redemptionTime 赎回时间Unix时间戳
* @param _initialWusdPrice 初始WUSD价格精度1e30传0则使用默认值1.0
* @param _initialYtPrice 初始YT价格精度1e30传0则使用默认值1.0 * @param _initialYtPrice 初始YT价格精度1e30传0则使用默认值1.0
*
* @dev 价格精度为1e30
*/ */
function initialize( function initialize(
string memory _name, string memory _name,
string memory _symbol, string memory _symbol,
address _manager, address _manager,
uint256 _hardCap, uint256 _hardCap,
address _wusd, address _usdc,
uint256 _redemptionTime, uint256 _redemptionTime,
uint256 _initialWusdPrice, uint256 _initialYtPrice,
uint256 _initialYtPrice address _usdcPriceFeed
) external initializer { ) external initializer {
wusdAddress = _wusd == address(0)
? 0x7Cd017ca5ddb86861FA983a34b5F495C6F898c41
: _wusd;
__ERC20_init(_name, _symbol); __ERC20_init(_name, _symbol);
__UUPSUpgradeable_init(); __UUPSUpgradeable_init();
__ReentrancyGuard_init(); __ReentrancyGuard_init();
__Pausable_init(); __Pausable_init();
if (_usdcPriceFeed == address(0)) revert InvalidPriceFeed();
usdcPriceFeed = AggregatorV3Interface(_usdcPriceFeed);
usdcAddress = _usdc;
// 获取USDC的decimals
usdcDecimals = IERC20Metadata(usdcAddress).decimals();
factory = msg.sender; factory = msg.sender;
manager = _manager; manager = _manager;
hardCap = _hardCap; hardCap = _hardCap;
// 使用传入的初始价格如果为0则使用默认值1.0 // 使用传入的初始价格如果为0则使用默认值1.0
wusdPrice = _initialWusdPrice == 0 ? PRICE_PRECISION : _initialWusdPrice;
ytPrice = _initialYtPrice == 0 ? PRICE_PRECISION : _initialYtPrice; ytPrice = _initialYtPrice == 0 ? PRICE_PRECISION : _initialYtPrice;
// 设置赎回时间 // 设置赎回时间
@@ -164,6 +173,42 @@ contract YTAssetVault is
*/ */
function _authorizeUpgrade(address newImplementation) internal override onlyFactory {} function _authorizeUpgrade(address newImplementation) internal override onlyFactory {}
/**
* @notice 获取并验证USDC价格从Chainlink
* @return 返回uint256格式的USDC价格精度为1e8
*/
function _getUSDCPrice() internal view returns (uint256) {
(
/* uint80 roundId */,
int256 price,
/* uint256 startedAt */,
/* uint256 updatedAt */,
/* uint80 answeredInRound */
) = usdcPriceFeed.latestRoundData();
if (price <= 0) revert InvalidChainlinkPrice();
return uint256(price);
}
/**
* @notice 计算价格转换因子
* @dev 转换因子 = 10^(ytDecimals) * PRICE_PRECISION / (10^(usdcDecimals) * CHAINLINK_PRICE_PRECISION)
* @return 价格转换因子
*/
function _getPriceConversionFactor() internal view returns (uint256) {
uint8 ytDecimals = decimals();
// 分子: 10^ytDecimals * PRICE_PRECISION (1e30)
uint256 numerator = (10 ** ytDecimals) * PRICE_PRECISION;
// 分母: 10^usdcDecimals * CHAINLINK_PRICE_PRECISION (1e8)
uint256 denominator = (10 ** usdcDecimals) * CHAINLINK_PRICE_PRECISION;
// 返回转换因子
return numerator / denominator;
}
/** /**
* @notice 设置硬顶 * @notice 设置硬顶
* @param _hardCap 新的硬顶值 * @param _hardCap 新的硬顶值
@@ -210,54 +255,56 @@ contract YTAssetVault is
/** /**
* @notice 更新价格仅manager可调用 * @notice 更新价格仅manager可调用
* @param _wusdPrice WUSD价格精度1e30
* @param _ytPrice YT价格精度1e30 * @param _ytPrice YT价格精度1e30
*/ */
function updatePrices(uint256 _wusdPrice, uint256 _ytPrice) external onlyFactory { function updatePrices(uint256 _ytPrice) external onlyFactory {
if (_wusdPrice == 0 || _ytPrice == 0) revert InvalidPrice(); if (_ytPrice == 0) revert InvalidPrice();
wusdPrice = _wusdPrice;
ytPrice = _ytPrice; ytPrice = _ytPrice;
emit PriceUpdated(_wusdPrice, _ytPrice, block.timestamp); emit PriceUpdated(_ytPrice, block.timestamp);
} }
/** /**
* @notice 用WUSD购买YT * @notice 用USDC购买YT
* @param _wusdAmount 支付的WUSD数量 * @param _usdcAmount 支付的USDC数量
* @return ytAmount 实际获得的YT数量 * @return ytAmount 实际获得的YT数量
* @dev 首次购买时YT价格 = WUSD价格1:1兑换 * @dev 首次购买时YT价格 = USDC价格1:1兑换
*/ */
function depositYT(uint256 _wusdAmount) function depositYT(uint256 _usdcAmount)
external external
nonReentrant nonReentrant
whenNotPaused whenNotPaused
returns (uint256 ytAmount) returns (uint256 ytAmount)
{ {
if (_wusdAmount == 0) revert InvalidAmount(); if (_usdcAmount == 0) revert InvalidAmount();
uint256 usdcPrice = _getUSDCPrice();
uint256 conversionFactor = _getPriceConversionFactor();
// 计算可以购买的YT数量 // 计算可以购买的YT数量
ytAmount = (_wusdAmount * wusdPrice) / ytPrice; // ytAmount = _usdcAmount * usdcPrice * conversionFactor / ytPrice
ytAmount = (_usdcAmount * usdcPrice * conversionFactor) / ytPrice;
// 检查硬顶 // 检查硬顶
if (hardCap > 0 && totalSupply() + ytAmount > hardCap) { if (hardCap > 0 && totalSupply() + ytAmount > hardCap) {
revert HardCapExceeded(); revert HardCapExceeded();
} }
// 转入WUSD // 转入USDC
IERC20(wusdAddress).safeTransferFrom(msg.sender, address(this), _wusdAmount); IERC20(usdcAddress).safeTransferFrom(msg.sender, address(this), _usdcAmount);
// 铸造YT // 铸造YT
_mint(msg.sender, ytAmount); _mint(msg.sender, ytAmount);
emit Buy(msg.sender, _wusdAmount, ytAmount); emit Buy(msg.sender, _usdcAmount, ytAmount);
} }
/** /**
* @notice 提交YT提现请求需要等到统一赎回时间 * @notice 提交YT提现请求需要等到统一赎回时间
* @param _ytAmount 卖出的YT数量 * @param _ytAmount 卖出的YT数量
* @return requestId 提现请求ID * @return requestId 提现请求ID
* @dev 用户提交请求后YT会立即销毁但WUSD需要等待批量处理后才能领取 * @dev 用户提交请求后YT会立即销毁
*/ */
function withdrawYT(uint256 _ytAmount) function withdrawYT(uint256 _ytAmount)
external external
@@ -272,9 +319,13 @@ contract YTAssetVault is
if (block.timestamp < nextRedemptionTime) { if (block.timestamp < nextRedemptionTime) {
revert StillInLockPeriod(); revert StillInLockPeriod();
} }
uint256 usdcPrice = _getUSDCPrice();
uint256 conversionFactor = _getPriceConversionFactor();
// 计算可以换取的WUSD数量 // 计算可以换取的USDC数量
uint256 wusdAmount = (_ytAmount * ytPrice) / wusdPrice; // usdcAmount = _ytAmount * ytPrice / (usdcPrice * conversionFactor)
uint256 usdcAmount = (_ytAmount * ytPrice) / (usdcPrice * conversionFactor);
// 销毁YT代币 // 销毁YT代币
_burn(msg.sender, _ytAmount); _burn(msg.sender, _ytAmount);
@@ -284,7 +335,7 @@ contract YTAssetVault is
withdrawRequests[requestId] = WithdrawRequest({ withdrawRequests[requestId] = WithdrawRequest({
user: msg.sender, user: msg.sender,
ytAmount: _ytAmount, ytAmount: _ytAmount,
wusdAmount: wusdAmount, usdcAmount: usdcAmount,
requestTime: block.timestamp, requestTime: block.timestamp,
queueIndex: requestId, queueIndex: requestId,
processed: false processed: false
@@ -299,14 +350,14 @@ contract YTAssetVault is
// 增加待处理请求计数 // 增加待处理请求计数
pendingRequestsCount++; pendingRequestsCount++;
emit WithdrawRequestCreated(requestId, msg.sender, _ytAmount, wusdAmount, requestId); emit WithdrawRequestCreated(requestId, msg.sender, _ytAmount, usdcAmount, requestId);
} }
/** /**
* @notice 批量处理提现请求仅manager或factory可调用 * @notice 批量处理提现请求仅manager或factory可调用
* @param _batchSize 本批次最多处理的请求数量 * @param _batchSize 本批次最多处理的请求数量
* @return processedCount 实际处理的请求数量 * @return processedCount 实际处理的请求数量
* @return totalDistributed 实际分发的WUSD总量 * @return totalDistributed 实际分发的USDC总量
* @dev 按照请求ID顺序即时间先后依次处理遇到资金不足时停止 * @dev 按照请求ID顺序即时间先后依次处理遇到资金不足时停止
*/ */
function processBatchWithdrawals(uint256 _batchSize) function processBatchWithdrawals(uint256 _batchSize)
@@ -322,7 +373,7 @@ contract YTAssetVault is
if (_batchSize == 0) revert InvalidBatchSize(); if (_batchSize == 0) revert InvalidBatchSize();
uint256 availableWUSD = IERC20(wusdAddress).balanceOf(address(this)); uint256 availableUSDC = IERC20(usdcAddress).balanceOf(address(this));
uint256 startIndex = processedUpToIndex; uint256 startIndex = processedUpToIndex;
for (uint256 i = processedUpToIndex; i < requestIdCounter && processedCount < _batchSize; i++) { for (uint256 i = processedUpToIndex; i < requestIdCounter && processedCount < _batchSize; i++) {
@@ -333,25 +384,25 @@ contract YTAssetVault is
continue; continue;
} }
// 检查是否有足够的WUSD // 检查是否有足够的USDC
if (availableWUSD >= request.wusdAmount) { if (availableUSDC >= request.usdcAmount) {
// 转账WUSD给用户 // 转账USDC给用户
IERC20(wusdAddress).safeTransfer(request.user, request.wusdAmount); IERC20(usdcAddress).safeTransfer(request.user, request.usdcAmount);
// 标记为已处理 // 标记为已处理
request.processed = true; request.processed = true;
// 更新统计 // 更新统计
availableWUSD -= request.wusdAmount; availableUSDC -= request.usdcAmount;
totalDistributed += request.wusdAmount; totalDistributed += request.usdcAmount;
processedCount++; processedCount++;
// 减少待处理请求计数 // 减少待处理请求计数
pendingRequestsCount--; pendingRequestsCount--;
emit WithdrawRequestProcessed(i, request.user, request.wusdAmount); emit WithdrawRequestProcessed(i, request.user, request.usdcAmount);
} else { } else {
// WUSD不足停止处理 // USDC不足,停止处理
break; break;
} }
} }
@@ -467,18 +518,18 @@ contract YTAssetVault is
} }
/** /**
* @notice 提取WUSD用于外部投资 * @notice 提取USDC用于外部投资
* @param _to 接收地址 * @param _to 接收地址
* @param _amount 提取数量 * @param _amount 提取数量
*/ */
function withdrawForManagement(address _to, uint256 _amount) external onlyManager nonReentrant whenNotPaused { function withdrawForManagement(address _to, uint256 _amount) external onlyManager nonReentrant whenNotPaused {
if (_amount == 0) revert InvalidAmount(); if (_amount == 0) revert InvalidAmount();
uint256 availableAssets = IERC20(wusdAddress).balanceOf(address(this)); uint256 availableAssets = IERC20(usdcAddress).balanceOf(address(this));
if (_amount > availableAssets) revert InvalidAmount(); if (_amount > availableAssets) revert InvalidAmount();
managedAssets += _amount; managedAssets += _amount;
IERC20(wusdAddress).safeTransfer(_to, _amount); IERC20(usdcAddress).safeTransfer(_to, _amount);
emit AssetsWithdrawn(_to, _amount); emit AssetsWithdrawn(_to, _amount);
} }
@@ -499,8 +550,8 @@ contract YTAssetVault is
managedAssets -= _amount; managedAssets -= _amount;
} }
// 从manager转入WUSD到合约 // 从manager转入USDC到合约
IERC20(wusdAddress).safeTransferFrom(msg.sender, address(this), _amount); IERC20(usdcAddress).safeTransferFrom(msg.sender, address(this), _amount);
emit AssetsDeposited(_amount); emit AssetsDeposited(_amount);
} }
@@ -510,33 +561,37 @@ contract YTAssetVault is
* @return 总资产 = 合约余额 + 被管理的资产 * @return 总资产 = 合约余额 + 被管理的资产
*/ */
function totalAssets() public view returns (uint256) { function totalAssets() public view returns (uint256) {
return IERC20(wusdAddress).balanceOf(address(this)) + managedAssets; return IERC20(usdcAddress).balanceOf(address(this)) + managedAssets;
} }
/** /**
* @notice 获取空闲资产(可用于提取的资产) * @notice 获取空闲资产(可用于提取的资产)
* @return 合约中实际持有的WUSD数量 * @return 合约中实际持有的USDC数量
*/ */
function idleAssets() public view returns (uint256) { function idleAssets() public view returns (uint256) {
return IERC20(wusdAddress).balanceOf(address(this)); return IERC20(usdcAddress).balanceOf(address(this));
} }
/** /**
* @notice 预览购买:计算支付指定WUSD可获得的YT数量 * @notice 预览购买计算支付指定USDC可获得的YT数量
* @param _wusdAmount 支付的WUSD数量 * @param _usdcAmount 支付的USDC数量
* @return ytAmount 可获得的YT数量 * @return ytAmount 可获得的YT数量
*/ */
function previewBuy(uint256 _wusdAmount) external view returns (uint256 ytAmount) { function previewBuy(uint256 _usdcAmount) external view returns (uint256 ytAmount) {
ytAmount = (_wusdAmount * wusdPrice) / ytPrice; uint256 usdcPrice = _getUSDCPrice();
uint256 conversionFactor = _getPriceConversionFactor();
ytAmount = (_usdcAmount * usdcPrice * conversionFactor) / ytPrice;
} }
/** /**
* @notice 预览卖出计算卖出指定YT可获得的WUSD数量 * @notice 预览卖出计算卖出指定YT可获得的USDC数量
* @param _ytAmount 卖出的YT数量 * @param _ytAmount 卖出的YT数量
* @return wusdAmount 可获得的WUSD数量 * @return usdcAmount 可获得的USDC数量
*/ */
function previewSell(uint256 _ytAmount) external view returns (uint256 wusdAmount) { function previewSell(uint256 _ytAmount) external view returns (uint256 usdcAmount) {
wusdAmount = (_ytAmount * ytPrice) / wusdPrice; uint256 usdcPrice = _getUSDCPrice();
uint256 conversionFactor = _getPriceConversionFactor();
usdcAmount = (_ytAmount * ytPrice) / (usdcPrice * conversionFactor);
} }
/** /**
@@ -548,16 +603,16 @@ contract YTAssetVault is
uint256 _managedAssets, uint256 _managedAssets,
uint256 _totalSupply, uint256 _totalSupply,
uint256 _hardCap, uint256 _hardCap,
uint256 _wusdPrice, uint256 _usdcPrice,
uint256 _ytPrice, uint256 _ytPrice,
uint256 _nextRedemptionTime uint256 _nextRedemptionTime
) { ) {
_usdcPrice = _getUSDCPrice();
_totalAssets = totalAssets(); _totalAssets = totalAssets();
_idleAssets = idleAssets(); _idleAssets = idleAssets();
_managedAssets = managedAssets; _managedAssets = managedAssets;
_totalSupply = totalSupply(); _totalSupply = totalSupply();
_hardCap = hardCap; _hardCap = hardCap;
_wusdPrice = wusdPrice;
_ytPrice = ytPrice; _ytPrice = ytPrice;
_nextRedemptionTime = nextRedemptionTime; _nextRedemptionTime = nextRedemptionTime;
} }

View File

@@ -1,12 +0,0 @@
{
"421614": {
"lendingFactory": "0x7f103156778058aEEDa9d65c5Dd5d6eB7E73fC74",
"configuratorProxy": "0x050ACf48e82d3688A93180082f7adeA015d78892",
"configuratorImpl": "0x12F6b84017E70C85Bf9EF2CEF320BccFd7E7314B",
"lendingImpl": "0x9a84efc5BFd82cC3A6B24BE00DF2FD4716C51A87",
"timestamp": "2025-12-22T06:07:41.196Z",
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"lendingProxy": "0x6D12F383d58Fb05f00799dEB5742CC0EF28Cf038",
"configTimestamp": "2025-12-22T06:11:34.649Z"
}
}

View File

@@ -0,0 +1,21 @@
{
"network": "arbSepolia",
"chainId": "421614",
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"timestamp": "2025-12-24T08:07:32.332Z",
"contracts": {
"USDC": {
"address": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
"description": "USDC代币地址已存在的合约"
},
"ChainlinkUSDCPriceFeed": {
"address": "0x0153002d20B96532C639313c2d54c3dA09109309",
"description": "Chainlink USDC/USD 价格预言机",
"precision": "1e8"
}
},
"notes": {
"bsc": "BSC主网的USDC是18位精度",
"arbSepolia": "Arbitrum Sepolia的USDC是6位精度"
}
}

View File

@@ -2,66 +2,50 @@
"network": "arbSepolia", "network": "arbSepolia",
"chainId": "421614", "chainId": "421614",
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d", "deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"timestamp": "2025-12-18T03:48:32.768Z", "timestamp": "2025-12-24T08:11:26.455Z",
"wusdAddress": "0x6d2bf81a631dFE19B2f348aE92cF6Ef41ca2DF98", "usdcAddress": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
"usdcPriceFeedAddress": "0x0153002d20B96532C639313c2d54c3dA09109309",
"defaultHardCap": "10000000000000000000000000", "defaultHardCap": "10000000000000000000000000",
"contracts": { "contracts": {
"YTAssetVault": { "YTAssetVault": {
"implementation": "0xcBaD1799D5E33A3bd9c1A8eD48501195c28c4f14" "implementation": "0x8097a7B04989c4D8B155Fd5DaF396d014808D7F7"
}, },
"YTAssetFactory": { "YTAssetFactory": {
"proxy": "0x982716f32F10BCB5B5944c1473a8992354bF632b", "proxy": "0xb5Ddb2C45874f04aD0d48F3bB6b0748b1D06814C",
"implementation": "0x310755c2a15f03bf94689B0A730BbFa82A20fce4" "implementation": "0xcD175992dE5EfF46673dBaAb12979bc4fcC0f0f6"
} }
}, },
"vaults": [ "vaults": [
{ {
"name": "YT Token A", "name": "YT Token A",
"symbol": "YT-A", "symbol": "YT-A",
"address": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748", "address": "0x97204190B35D9895a7a47aa7BaC61ac08De3cF05",
"index": "0", "index": "0",
"manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d", "manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"hardCap": "10000000000000000000000000", "hardCap": "10000000000000000000000000",
"redemptionTime": 1797565718, "redemptionTime": 1798099928,
"wusdPrice": "1000000000000000000000000000000", "ytPrice": "1000000000000000000000000000000"
"ytPrice": "1000000000000000000000000000000",
"implementationAddress": "0xcBaD1799D5E33A3bd9c1A8eD48501195c28c4f14",
"lastUpgraded": "2025-12-19T05:15:25.594Z"
}, },
{ {
"name": "YT Token B", "name": "YT Token B",
"symbol": "YT-B", "symbol": "YT-B",
"address": "0x719D16769757b7E87a89A3B3e0Cc259c5705135c", "address": "0x181ef4011c35C4a2Fda08eBC5Cf509Ef58E553fF",
"index": "1", "index": "1",
"manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d", "manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"hardCap": "10000000000000000000000000", "hardCap": "10000000000000000000000000",
"redemptionTime": 1797565718, "redemptionTime": 1798099928,
"wusdPrice": "1000000000000000000000000000000", "ytPrice": "1000000000000000000000000000000"
"ytPrice": "1000000000000000000000000000000",
"implementationAddress": "0xcBaD1799D5E33A3bd9c1A8eD48501195c28c4f14",
"lastUpgraded": "2025-12-19T05:15:29.413Z"
}, },
{ {
"name": "YT Token C", "name": "YT Token C",
"symbol": "YT-C", "symbol": "YT-C",
"address": "0xcB45C64c2314Ed6EBe916C7F71D575AebA19c8Ce", "address": "0xE9A5b9f3a2Eda4358f81d4E2eF4f3280A664e5B0",
"index": "2", "index": "2",
"manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d", "manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"hardCap": "10000000000000000000000000", "hardCap": "10000000000000000000000000",
"redemptionTime": 1797565718, "redemptionTime": 1798099928,
"wusdPrice": "1000000000000000000000000000000", "ytPrice": "1000000000000000000000000000000"
"ytPrice": "1000000000000000000000000000000",
"implementationAddress": "0xcBaD1799D5E33A3bd9c1A8eD48501195c28c4f14",
"lastUpgraded": "2025-12-19T05:15:34.429Z"
} }
], ],
"lastUpdate": "2025-12-19T05:15:34.430Z", "lastUpdate": "2025-12-24T08:12:25.131Z"
"upgradeHistory": [
{
"timestamp": "2025-12-19T05:15:34.430Z",
"oldImplementation": "0x5f0BB22F72BFc2F0903038c46E03d49E254EBCD4",
"newImplementation": "0xcBaD1799D5E33A3bd9c1A8eD48501195c28c4f14",
"upgrader": "0xa013422A5918CD099C63c8CC35283EACa99a705d"
}
]
} }

View File

@@ -1,32 +1,46 @@
{ {
"timestamp": "2025-12-18T03:50:23.682Z", "timestamp": "2025-12-24T08:20:12.674Z",
"operator": "0xa013422A5918CD099C63c8CC35283EACa99a705d", "operator": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"whitelistedVaults": [ "whitelistedTokens": {
{ "ytTokens": [
"name": "YT Token A", {
"symbol": "YT-A", "name": "YT Token A",
"address": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748", "symbol": "YT-A",
"weight": 4000, "address": "0x97204190B35D9895a7a47aa7BaC61ac08De3cF05",
"maxUsdyAmount": "45000000000000000000000000", "weight": 4000,
"price": "1000000000000000000000000000000" "maxUsdyAmount": "45000000000000000000000000",
}, "price": "1000000000000000000000000000000",
{ "isStable": false
"name": "YT Token B", },
"symbol": "YT-B", {
"address": "0x719D16769757b7E87a89A3B3e0Cc259c5705135c", "name": "YT Token B",
"weight": 3000, "symbol": "YT-B",
"maxUsdyAmount": "35000000000000000000000000", "address": "0x181ef4011c35C4a2Fda08eBC5Cf509Ef58E553fF",
"price": "1000000000000000000000000000000" "weight": 3000,
}, "maxUsdyAmount": "35000000000000000000000000",
{ "price": "1000000000000000000000000000000",
"name": "YT Token C", "isStable": false
"symbol": "YT-C", },
"address": "0xcB45C64c2314Ed6EBe916C7F71D575AebA19c8Ce", {
"weight": 2000, "name": "YT Token C",
"maxUsdyAmount": "25000000000000000000000000", "symbol": "YT-C",
"price": "1000000000000000000000000000000" "address": "0xE9A5b9f3a2Eda4358f81d4E2eF4f3280A664e5B0",
"weight": 2000,
"maxUsdyAmount": "25000000000000000000000000",
"price": "1000000000000000000000000000000",
"isStable": false
}
],
"usdc": {
"name": "USDC",
"symbol": "USDC",
"address": "0x75faf114eafb1BDbe2F0316DF893fd58CE46AA4d",
"weight": 1000,
"maxUsdyAmount": "30000000000000",
"priceSource": "Chainlink (自动)",
"isStable": true
} }
], },
"totalWeight": "9000", "totalWeight": "10000",
"wusdPriceSource": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748" "poolComposition": "USDC/YT-A/YT-B/YT-C"
} }

View File

@@ -1,15 +0,0 @@
{
"network": "arbSepolia",
"chainId": "421614",
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"timestamp": "2025-12-18T03:47:04.283Z",
"contracts": {
"WUSD": {
"proxy": "0x6d2bf81a631dFE19B2f348aE92cF6Ef41ca2DF98",
"implementation": "0xA6674E25670563f881aABCc25845757cEecb8d86",
"name": "Wrapped USD",
"symbol": "WUSD",
"decimals": 18
}
}
}

View File

@@ -2,27 +2,27 @@
"network": "arbSepolia", "network": "arbSepolia",
"chainId": "421614", "chainId": "421614",
"configurer": "0xa013422A5918CD099C63c8CC35283EACa99a705d", "configurer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"timestamp": "2025-12-18T03:49:43.544Z", "timestamp": "2025-12-24T08:14:12.730Z",
"configuration": { "configuration": {
"permissions": { "permissions": {
"usdyVaults": [ "usdyVaults": [
"0xbC2e4f06601B92B3F430962a8f0a7E8c378ce54e", "0xc110C84b107126c4E5b1CE598d3602ec0260D98B",
"0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6" "0x691Aa0fF71a330454f50452925A3005Ae8412902"
], ],
"ytlpMinters": [ "ytlpMinters": [
"0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6" "0x691Aa0fF71a330454f50452925A3005Ae8412902"
], ],
"vaultPoolManager": "0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6", "vaultPoolManager": "0x691Aa0fF71a330454f50452925A3005Ae8412902",
"vaultSwappers": [ "vaultSwappers": [
"0x953758c02ec49F1f67fE2a8E3F67C434FeC5aB9d" "0x15dA695F8ad005c2Ccd0AEC57C902c404E510Aab"
], ],
"poolManagerHandlers": [ "poolManagerHandlers": [
"0x953758c02ec49F1f67fE2a8E3F67C434FeC5aB9d" "0x15dA695F8ad005c2Ccd0AEC57C902c404E510Aab"
], ],
"priceFeedKeepers": [ "priceFeedKeepers": [
"0xa013422A5918CD099C63c8CC35283EACa99a705d" "0xa013422A5918CD099C63c8CC35283EACa99a705d"
], ],
"priceFeedWusdSource": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748" "usdcPriceSource": "Chainlink (自动)"
}, },
"parameters": { "parameters": {
"dynamicFees": true, "dynamicFees": true,

View File

@@ -2,31 +2,31 @@
"network": "arbSepolia", "network": "arbSepolia",
"chainId": "421614", "chainId": "421614",
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d", "deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
"timestamp": "2025-12-18T03:48:03.817Z", "timestamp": "2025-12-24T08:10:20.679Z",
"contracts": { "contracts": {
"USDY": { "USDY": {
"proxy": "0x54551451E14D3d3418e4Aa9F31e9E8573fd37053", "proxy": "0x664dF9c24b184f8D2533BfFF1E8cbff939978879",
"implementation": "0xb14d186d4EAcE8131a449126c6208165a3F5FC5b" "implementation": "0x88b8E9aE3789A2c06C5df536C71e691cD6780a65"
}, },
"YTLPToken": { "YTLPToken": {
"proxy": "0xf5206D958f692556603806A8f65bB106E23d1776", "proxy": "0x102e3F25Ef0ad9b0695C8F2daF8A1262437eEfc3",
"implementation": "0x0C3fa01b2D0596B4190edEF1B77534237231C77e" "implementation": "0xE071419995aE63079af74E7f8eB1643B6F6fb2d7"
}, },
"YTPriceFeed": { "YTPriceFeed": {
"proxy": "0x9364D3aF669886883C26EC0ff32000719491452A", "proxy": "0xdC18de7D5A439cb90F149Eb62bAace55557d20AA",
"implementation": "0x83bdD4dc68AE608AEDE0f232e2d826b09B19004f" "implementation": "0x7088891AeAA1d6795bA49C1871199EbAc3892599"
}, },
"YTVault": { "YTVault": {
"proxy": "0xbC2e4f06601B92B3F430962a8f0a7E8c378ce54e", "proxy": "0xc110C84b107126c4E5b1CE598d3602ec0260D98B",
"implementation": "0x61278a2EBFC07eF0F7f84407291aAD07DA596AB2" "implementation": "0xaF332cd890A394501E191Aa683Fe6aF4227C2623"
}, },
"YTPoolManager": { "YTPoolManager": {
"proxy": "0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6", "proxy": "0x691Aa0fF71a330454f50452925A3005Ae8412902",
"implementation": "0x96Fe19188c3c7d0EDA441dafC7976fBB3526d28c" "implementation": "0x0D4625A5d3b696684ECf00b49F1B68297A8b3154"
}, },
"YTRewardRouter": { "YTRewardRouter": {
"proxy": "0x953758c02ec49F1f67fE2a8E3F67C434FeC5aB9d", "proxy": "0x15dA695F8ad005c2Ccd0AEC57C902c404E510Aab",
"implementation": "0x7A322e130fb10C3d3e2297A6C362E0d36459F1B0" "implementation": "0xa77E96720924c7CBc70D4B0E3842a962f94931dc"
} }
} }
} }

View File

@@ -499,7 +499,7 @@
│ │ │ YT-A (原有) │ 30000 │ 30.0% │ 27.27% │ ← 自动变化│ │ │ │ │ YT-A (原有) │ 30000 │ 30.0% │ 27.27% │ ← 自动变化│ │
│ │ │ YT-B (原有) │ 30000 │ 30.0% │ 27.27% │ │ │ │ │ │ YT-B (原有) │ 30000 │ 30.0% │ 27.27% │ │ │
│ │ │ YT-C (原有) │ 30000 │ 30.0% │ 27.27% │ │ │ │ │ │ YT-C (原有) │ 30000 │ 30.0% │ 27.27% │ │ │
│ │ │ WUSD (原有) │ 10000 │ 10.0% │ 9.09% │ │ │ │ │ │ USDC (原有) │ 10000 │ 10.0% │ 9.09% │ │ │
│ │ │ YT-D (新增) │ 10000 │ - │ 9.09% │ ← 新增 │ │ │ │ │ YT-D (新增) │ 10000 │ - │ 9.09% │ ← 新增 │ │
│ │ ├──────────────┼────────┼──────────┼──────────┤ │ │ │ │ ├──────────────┼────────┼──────────┼──────────┤ │ │
│ │ │ 总计 │ 110000 │ 100% │ 100% │ │ │ │ │ │ 总计 │ 110000 │ 100% │ 100% │ │ │
@@ -534,8 +534,10 @@
│ ② 初始化价格 (如果需要) │ │ ② 初始化价格 (如果需要) │
│ forceUpdatePrice(YT-D, 1e30) // 初始价格 $1.00 │ │ forceUpdatePrice(YT-D, 1e30) // 初始价格 $1.00 │
│ │ │ │
│ 注意: YT代币需要实现 assetPrice() 接口 │ 注意:
价格预言机会自动读取该接口获取价格 • YT代币需要实现 ytPrice() 接口
│ • 价格预言机会自动读取该接口获取YT价格 │
│ • USDC价格自动从Chainlink获取无需手动配置 │
└─────────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────────┘
│ 3. 配置完成 │ 3. 配置完成
@@ -569,9 +571,9 @@
┌─────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────┐
│ YT代币必须实现的接口 │ │ YT代币必须实现的接口 │
│ │ │ │
│ interface IYTToken { │ interface IYTAssetVault {
│ // 必需返回当前资产价格30位精度 │ // 必需:返回当前YT资产价格30位精度
│ function assetPrice() external view returns (uint256); │ │ function ytPrice() external view returns (uint256);
│ │ │ │
│ // 可选:返回最后价格更新时间 │ │ // 可选:返回最后价格更新时间 │
│ function lastPriceUpdate() external view returns (uint256); │ │ function lastPriceUpdate() external view returns (uint256); │
@@ -584,9 +586,14 @@
│ external returns (bool); │ │ external returns (bool); │
│ } │ │ } │
│ │ │ │
│ 价格示例: YT价格示例 (1e30精度):
│ $1.00 = 1 × 10^30 = 1000000000000000000000000000000 │ │ $1.00 = 1 × 10^30 = 1000000000000000000000000000000 │
│ $0.998 = 998000000000000000000000000000 │ │ $0.998 = 998000000000000000000000000000 │
│ │
│ USDC价格从Chainlink获取1e8精度: │
│ $1.00 = 100000000 (1e8) │
│ $0.998 = 99800000 │
│ 自动转换为1e30精度用于内部计算 │
└─────────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────────┘
``` ```
@@ -640,7 +647,7 @@
│ │ │ YT-A │ 30000 │ 30% │ │ │ │ │ │ YT-A │ 30000 │ 30% │ │ │
│ │ │ YT-B │ 30000 │ 30% │ │ │ │ │ │ YT-B │ 30000 │ 30% │ │ │
│ │ │ YT-C │ 30000 │ 30% │ │ │ │ │ │ YT-C │ 30000 │ 30% │ │ │
│ │ │ WUSD │ 10000 │ 10% │ │ │ │ │ │ USDC │ 10000 │ 10% │ │ │
│ │ │ YT-D (删除) │ 0 │ - │ ← 已移除 │ │ │ │ │ YT-D (删除) │ 0 │ - │ ← 已移除 │ │
│ │ ├──────────────┼────────┼────────┤ │ │ │ │ ├──────────────┼────────┼────────┤ │ │
│ │ │ 总计 │ 100000 │ 100% │ │ │ │ │ │ 总计 │ 100000 │ 100% │ │ │
@@ -783,25 +790,29 @@
## 6. 系统部署和初始化流程 ## 6. 系统部署和初始化流程
### 6.1 部署 YTPriceFeed优化版 ### 6.1 部署 YTPriceFeed使用 Chainlink
``` ```
┌─────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────┐
│ 部署者 (Deployer) │ │ 部署者 (Deployer) │
└────────────────────────────┬────────────────────────────────────────┘ └────────────────────────────┬────────────────────────────────────────┘
│ 1. 首先部署 WUSD │ 1. 准备 USDC 和 Chainlink 地址
┌─────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────┐
部署 WUSD 合约 准备外部合约地址
│ ───────────────────────────────────────────────────────────────── │ │ ───────────────────────────────────────────────────────────────── │
WUSD wusd = new WUSD() • USDC 代币地址BSC主网
wusd.initialize("Wrapped USD", "WUSD") usdc = 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d
│ 注意BSC主网USDC是18位精度 │
│ │ │ │
得到: 0x7Cd017ca5ddb86861FA983a34b5F495C6F898c41 • Chainlink USDC/USD 价格预言机地址BSC主网
│ usdcPriceFeed = 0x51597f405303C4377E36123cBc172b13269EA163 │
│ 精度1e8Chainlink标准
│ 价格示例:$1.00 = 100000000 (1e8) │
└────────────────────────────┬────────────────────────────────────────┘ └────────────────────────────┬────────────────────────────────────────┘
│ 2. 部署 YTPriceFeed传入WUSD地址 │ 2. 部署 YTPriceFeed传入USDC和Chainlink地址)
┌─────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────┐
│ 部署 YTPriceFeed可升级 │ 部署 YTPriceFeed可升级
@@ -809,7 +820,10 @@
│ const YTPriceFeed = await ethers.getContractFactory("YTPriceFeed") │ │ const YTPriceFeed = await ethers.getContractFactory("YTPriceFeed") │
│ const priceFeed = await upgrades.deployProxy( │ │ const priceFeed = await upgrades.deployProxy( │
│ YTPriceFeed, │ │ YTPriceFeed, │
│ [wusdAddress], // ← 初始化参数WUSD地址 │ [
│ usdcAddress, // ← USDC代币地址 │
│ usdcPriceFeedAddress // ← Chainlink预言机地址 │
│ ], │
│ { │ │ { │
│ kind: "uups", │ │ kind: "uups", │
│ initializer: "initialize" │ │ initializer: "initialize" │
@@ -817,29 +831,37 @@
│ ) │ │ ) │
└────────────────────────────┬────────────────────────────────────────┘ └────────────────────────────┬────────────────────────────────────────┘
│ 3. initialize(address _wusdAddress) │ 3. initialize(address _usdc, address _usdcPriceFeed)
┌─────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────┐
│ YTPriceFeed.initialize() │ │ YTPriceFeed.initialize() │
│ ───────────────────────────────────────────────────────────────── │ │ ───────────────────────────────────────────────────────────────── │
│ function initialize(address _wusdAddress) external initializer │ function initialize(
│ address _usdc, │
│ address _usdcPriceFeed │
│ ) external initializer │
│ │ │ │
│ 步骤: │ │ 步骤: │
│ ┌─────────────────────────────────────────────────────────────┐ │ │ ┌─────────────────────────────────────────────────────────────┐ │
│ │ ① __UUPSUpgradeable_init() │ │ │ │ ① __UUPSUpgradeable_init() │ │
│ │ • 初始化UUPS升级功能 │ │ │ │ • 初始化UUPS升级功能 │ │
│ │ │ │ │ │ │ │
│ │ ② 验证WUSD地址 │ │ │ │ ② 验证USDC地址 │ │
│ │ if (_wusdAddress == address(0)) revert InvalidAddress() │ │ │ │ if (_usdc == address(0)) revert InvalidAddress() │ │
│ │ ✓ 0x7Cd... 有效 │ │ │ │ ✓ 0x8AC... 有效 │ │
│ │ │ │ │ │ │ │
│ │ ③ 保存WUSD地址 │ │ │ │ ③ 验证Chainlink预言机地址 │ │
│ │ wusdAddress = _wusdAddress │ │ │ │ if (_usdcPriceFeed == address(0)) revert InvalidAddress()│ │
│ │ ✓ 0x515... 有效 │ │
│ │ │ │ │ │ │ │
│ │ ④ 设置治理地址 │ │ │ │ ④ 保存地址 │ │
│ │ usdc = _usdc │ │
│ │ usdcPriceFeed = AggregatorV3Interface(_usdcPriceFeed) │ │
│ │ │ │
│ │ ⑤ 设置治理地址 │ │
│ │ gov = msg.sender (部署者) │ │ │ │ gov = msg.sender (部署者) │ │
│ │ │ │ │ │ │ │
│ │ 设置默认参数 │ │ │ │ 设置默认参数 │ │
│ │ maxPriceChangeBps = 500 // 5% 最大价格变动 │ │ │ │ maxPriceChangeBps = 500 // 5% 最大价格变动 │ │
│ └─────────────────────────────────────────────────────────────┘ │ │ └─────────────────────────────────────────────────────────────┘ │
└────────────────────────────┬────────────────────────────────────────┘ └────────────────────────────┬────────────────────────────────────────┘
@@ -850,16 +872,20 @@
│ YTPriceFeed 就绪 │ │ YTPriceFeed 就绪 │
│ ───────────────────────────────────────────────────────────────── │ │ ───────────────────────────────────────────────────────────────── │
│ 状态: │ │ 状态: │
│ • wusdAddress: 已设置 ✓ │ • usdc: 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d ✓
│ • usdcPriceFeed: 0x51597f405303C4377E36123cBc172b13269EA163 ✓ │
│ • gov: 已设置 ✓ │ │ • gov: 已设置 ✓ │
│ • maxPriceChangeBps: 500 (5%) │ │ • maxPriceChangeBps: 500 (5%) │
• wusdPriceSource: 未设置(稍后配置)
│ 价格获取方式: │
│ • USDC价格从Chainlink实时获取自动更新
│ • YT代币价格从YTAssetVault.ytPrice()读取需keeper更新
│ │ │ │
│ 优势: │ │ 优势: │
│ ✓ 减少一个初始化参数 │ ✓ USDC价格实时准确Chainlink提供
│ ✓ WUSD地址在初始化时就确定 │ ✓ 无需手动更新USDC价格
│ ✓ 避免后续单独设置WUSD地址 │ ✓ 价格数据去中心化,更可靠
│ ✓ 简化部署流程 │ ✓ 支持价格验证(负数/零值检查)
└─────────────────────────────────────────────────────────────────────┘ └─────────────────────────────────────────────────────────────────────┘
``` ```
@@ -869,15 +895,16 @@
┌─────────────────────────────────────────────────────────────────────┐ ┌─────────────────────────────────────────────────────────────────────┐
│ 系统部署顺序 │ │ 系统部署顺序 │
│ │ │ │
│ 步骤 1: 部署 WUSD │ 步骤 1: 准备 USDC 和 Chainlink 地址
─→ WUSD.initialize("Wrapped USD", "WUSD") ─→ USDC: 0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d (BSC主网)
│ └─→ Chainlink USDC/USD: 0x51597f405303C4377E36123cBc172b13269EA163 │
│ │ │ │
│ 步骤 2: 部署代币合约 │ │ 步骤 2: 部署代币合约 │
│ ├─→ USDY.initialize() │ │ ├─→ USDY.initialize() │
│ └─→ YTLPToken.initialize() │ │ └─→ YTLPToken.initialize() │
│ │ │ │
│ 步骤 3: 部署 YTPriceFeed │ │ 步骤 3: 部署 YTPriceFeed │
│ └─→ YTPriceFeed.initialize(wusdAddress) ← 传入WUSD地址 │ └─→ YTPriceFeed.initialize(usdcAddress, usdcPriceFeedAddress)
│ │ │ │
│ 步骤 4: 部署 YTVault │ │ 步骤 4: 部署 YTVault │
│ └─→ YTVault.initialize(usdyAddress, priceFeedAddress) │ │ └─→ YTVault.initialize(usdyAddress, priceFeedAddress) │
@@ -907,9 +934,9 @@
│ └─→ poolManager.setHandler(routerAddress, true) │ │ └─→ poolManager.setHandler(routerAddress, true) │
│ │ │ │
│ 步骤 8: 配置 YTPriceFeed │ │ 步骤 8: 配置 YTPriceFeed │
│ ├─→ priceFeed.setWusdPriceSource(ytAssetVaultAddress) │
│ ├─→ priceFeed.setKeeper(keeperAddress, true) │ │ ├─→ priceFeed.setKeeper(keeperAddress, true) │
─→ priceFeed.setMaxPriceChangeBps(500) │ ─→ priceFeed.setMaxPriceChangeBps(500) │
│ └─→ 注意USDC价格自动从Chainlink获取无需手动设置 │
│ │ │ │
│ 步骤 9: 配置 YTVault 参数 │ │ 步骤 9: 配置 YTVault 参数 │
│ ├─→ vault.setSwapFees(30, 4, 50, 20) │ │ ├─→ vault.setSwapFees(30, 4, 50, 20) │

File diff suppressed because it is too large Load Diff

View File

@@ -7,3 +7,5 @@ cache_path = 'cache_forge'
via_ir = true via_ir = true
optimizer = true optimizer = true
optimizer_runs = 200 optimizer_runs = 200
offline = true
no_storage_caching = true

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"CONSOLE\":{\"details\":\"console.sol and console2.sol work by executing a staticcall to this address. Calculated as `address(uint160(uint88(bytes11(\\\"console.log\\\"))))`.\"},\"CREATE2_FACTORY\":{\"details\":\"Used when deploying with create2. Taken from https://github.com/Arachnid/deterministic-deployment-proxy.\"},\"DEFAULT_SENDER\":{\"details\":\"The default address for tx.origin and msg.sender. Calculated as `address(uint160(uint256(keccak256(\\\"foundry default caller\\\"))))`.\"},\"DEFAULT_TEST_CONTRACT\":{\"details\":\"The address of the first contract `CREATE`d by a running test contract. When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`.\"},\"MULTICALL3_ADDRESS\":{\"details\":\"Deterministic deployment address of the Multicall3 contract. Taken from https://www.multicall3.com.\"},\"SECP256K1_ORDER\":{\"details\":\"The order of the secp256k1 curve.\"},\"VM_ADDRESS\":{\"details\":\"Cheat code address. Calculated as `address(uint160(uint256(keccak256(\\\"hevm cheat code\\\"))))`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/Base.sol\":\"CommonBase\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/Base.sol\":{\"keccak256\":\"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d\",\"dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/Base.sol":"CommonBase"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/Base.sol":{"keccak256":"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf","urls":["bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d","dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":24} {"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"stateVariables\":{\"CONSOLE\":{\"details\":\"console.sol and console2.sol work by executing a staticcall to this address. Calculated as `address(uint160(uint88(bytes11(\\\"console.log\\\"))))`.\"},\"CREATE2_FACTORY\":{\"details\":\"Used when deploying with create2. Taken from https://github.com/Arachnid/deterministic-deployment-proxy.\"},\"DEFAULT_SENDER\":{\"details\":\"The default address for tx.origin and msg.sender. Calculated as `address(uint160(uint256(keccak256(\\\"foundry default caller\\\"))))`.\"},\"DEFAULT_TEST_CONTRACT\":{\"details\":\"The address of the first contract `CREATE`d by a running test contract. When running tests, each test contract is `CREATE`d by `DEFAULT_SENDER` with nonce 1. Calculated as `VM.computeCreateAddress(VM.computeCreateAddress(DEFAULT_SENDER, 1), 1)`.\"},\"MULTICALL3_ADDRESS\":{\"details\":\"Deterministic deployment address of the Multicall3 contract. Taken from https://www.multicall3.com.\"},\"SECP256K1_ORDER\":{\"details\":\"The order of the secp256k1 curve.\"},\"VM_ADDRESS\":{\"details\":\"Cheat code address. Calculated as `address(uint160(uint256(keccak256(\\\"hevm cheat code\\\"))))`.\"}},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/Base.sol\":\"CommonBase\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/Base.sol\":{\"keccak256\":\"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d\",\"dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/Base.sol":"CommonBase"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/Base.sol":{"keccak256":"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf","urls":["bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d","dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":25}

View File

@@ -1 +1 @@
{"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/Base.sol\":\"ScriptBase\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/Base.sol\":{\"keccak256\":\"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d\",\"dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/Base.sol":"ScriptBase"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/Base.sol":{"keccak256":"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf","urls":["bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d","dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":24} {"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/Base.sol\":\"ScriptBase\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/Base.sol\":{\"keccak256\":\"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d\",\"dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/Base.sol":"ScriptBase"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/Base.sol":{"keccak256":"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf","urls":["bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d","dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":25}

View File

@@ -1 +1 @@
{"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/Base.sol\":\"TestBase\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/Base.sol\":{\"keccak256\":\"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d\",\"dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/Base.sol":"TestBase"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/Base.sol":{"keccak256":"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf","urls":["bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d","dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":24} {"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/Base.sol\":\"TestBase\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/Base.sol\":{\"keccak256\":\"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d\",\"dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/Base.sol":"TestBase"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/Base.sol":{"keccak256":"0x4b2a5a85e045dcf6a082700c7252e43854c2eed88f860aaa18ec1e85218ae2bf","urls":["bzz-raw://98d060ed5be569a92d908fc358149039dc8f833d61973aa1b9d1d8235676bf6d","dweb:/ipfs/QmaWQpn5dJmbMS5skwmPPMeUWZG35BLkignPpcA3zyagEs"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":25}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"abi":[{"type":"function","name":"ytPrice","inputs":[],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"ytPrice()":"adcc40cb"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[],\"name\":\"ytPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IYTAssetVault.sol\":\"IYTAssetVault\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"contracts/interfaces/IYTAssetVault.sol\":{\"keccak256\":\"0xb0a83f0d960d0739bc31898eb3e04d817984a708c53c8b0eaa38c10cf79ce503\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://2036d1b7de81fb909e5af2842d97e5a5a55a9b43f1023ec3642c521c592d0f6e\",\"dweb:/ipfs/Qma3adh7SavnDX84zoyizeSQ7bS1NeihWCcnzqEw4rT9nE\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[{"inputs":[],"stateMutability":"view","type":"function","name":"ytPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"contracts/interfaces/IYTAssetVault.sol":"IYTAssetVault"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"contracts/interfaces/IYTAssetVault.sol":{"keccak256":"0xb0a83f0d960d0739bc31898eb3e04d817984a708c53c8b0eaa38c10cf79ce503","urls":["bzz-raw://2036d1b7de81fb909e5af2842d97e5a5a55a9b43f1023ec3642c521c592d0f6e","dweb:/ipfs/Qma3adh7SavnDX84zoyizeSQ7bS1NeihWCcnzqEw4rT9nE"],"license":"MIT"}},"version":1},"id":2}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1 @@
{"abi":[{"type":"function","name":"getPrice","inputs":[{"name":"_token","type":"address","internalType":"address"}],"outputs":[{"name":"","type":"uint256","internalType":"uint256"}],"stateMutability":"view"}],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{"getPrice(address)":"41976e09"},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[{\"inputs\":[{\"internalType\":\"address\",\"name\":\"_token\",\"type\":\"address\"}],\"name\":\"getPrice\",\"outputs\":[{\"internalType\":\"uint256\",\"name\":\"\",\"type\":\"uint256\"}],\"stateMutability\":\"view\",\"type\":\"function\"}],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"contracts/interfaces/IYTLendingPriceFeed.sol\":\"IYTLendingPriceFeed\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"contracts/interfaces/IYTLendingPriceFeed.sol\":{\"keccak256\":\"0x095fbfbd813f2647cecd69b4f24d666bfc6256b4d2aaeb2d09564ad300113a20\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://7a158c144cb7059613bfd3718c34a51a36402a69d38ae453f8b88ecf680ce47e\",\"dweb:/ipfs/QmQBKyxPu1LWuo4CWuNtwVDowWUgbdXiKRPXXhAgHE1uzR\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[{"inputs":[{"internalType":"address","name":"_token","type":"address"}],"stateMutability":"view","type":"function","name":"getPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}]}],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"contracts/interfaces/IYTLendingPriceFeed.sol":"IYTLendingPriceFeed"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"contracts/interfaces/IYTLendingPriceFeed.sol":{"keccak256":"0x095fbfbd813f2647cecd69b4f24d666bfc6256b4d2aaeb2d09564ad300113a20","urls":["bzz-raw://7a158c144cb7059613bfd3718c34a51a36402a69d38ae453f8b88ecf680ce47e","dweb:/ipfs/QmQBKyxPu1LWuo4CWuNtwVDowWUgbdXiKRPXXhAgHE1uzR"],"license":"MIT"}},"version":1},"id":4}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"StdChains provides information about EVM compatible chains that can be used in scripts/tests. For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the alias used in this contract, which can be found as the first argument to the `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. There are two main ways to use this contract: 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or `setChain(string memory chainAlias, Chain memory chain)` 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. The first time either of those are used, chains are initialized with the default set of RPC URLs. This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in `defaultRpcUrls`. The `setChain` function is straightforward, and it simply saves off the given chain data. The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say we want to retrieve the RPC URL for `mainnet`: - If you have specified data with `setChain`, it will return that. - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it is valid (e.g. a URL is specified, or an environment variable is given and exists). - If neither of the above conditions is met, the default data is returned. Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdChains.sol\":\"StdChains\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdChains.sol\":{\"keccak256\":\"0x8bed7472cb417f0e55ea37fe8cd34a54788d06a13de7c96e1448eae041744568\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6bf07369fee84b74edd61c8eb08bf71e3f4fdbb6ad24061996b4e2bfd42f3f69\",\"dweb:/ipfs/QmQhyYedzf8GtTc51495Lek1rZBQ6nigrGFXUpwHhN3RLa\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdChains.sol":"StdChains"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdChains.sol":{"keccak256":"0x8bed7472cb417f0e55ea37fe8cd34a54788d06a13de7c96e1448eae041744568","urls":["bzz-raw://6bf07369fee84b74edd61c8eb08bf71e3f4fdbb6ad24061996b4e2bfd42f3f69","dweb:/ipfs/QmQhyYedzf8GtTc51495Lek1rZBQ6nigrGFXUpwHhN3RLa"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":26} {"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"notice\":\"StdChains provides information about EVM compatible chains that can be used in scripts/tests. For each chain, the chain's name, chain ID, and a default RPC URL are provided. Chains are identified by their alias, which is the same as the alias in the `[rpc_endpoints]` section of the `foundry.toml` file. For best UX, ensure the alias in the `foundry.toml` file match the alias used in this contract, which can be found as the first argument to the `setChainWithDefaultRpcUrl` call in the `initializeStdChains` function. There are two main ways to use this contract: 1. Set a chain with `setChain(string memory chainAlias, ChainData memory chain)` or `setChain(string memory chainAlias, Chain memory chain)` 2. Get a chain with `getChain(string memory chainAlias)` or `getChain(uint256 chainId)`. The first time either of those are used, chains are initialized with the default set of RPC URLs. This is done in `initializeStdChains`, which uses `setChainWithDefaultRpcUrl`. Defaults are recorded in `defaultRpcUrls`. The `setChain` function is straightforward, and it simply saves off the given chain data. The `getChain` methods use `getChainWithUpdatedRpcUrl` to return a chain. For example, let's say we want to retrieve the RPC URL for `mainnet`: - If you have specified data with `setChain`, it will return that. - If you have configured a mainnet RPC URL in `foundry.toml`, it will return the URL, provided it is valid (e.g. a URL is specified, or an environment variable is given and exists). - If neither of the above conditions is met, the default data is returned. Summarizing the above, the prioritization hierarchy is `setChain` -> `foundry.toml` -> environment variable -> defaults.\",\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdChains.sol\":\"StdChains\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdChains.sol\":{\"keccak256\":\"0x8bed7472cb417f0e55ea37fe8cd34a54788d06a13de7c96e1448eae041744568\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://6bf07369fee84b74edd61c8eb08bf71e3f4fdbb6ad24061996b4e2bfd42f3f69\",\"dweb:/ipfs/QmQhyYedzf8GtTc51495Lek1rZBQ6nigrGFXUpwHhN3RLa\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdChains.sol":"StdChains"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdChains.sol":{"keccak256":"0x8bed7472cb417f0e55ea37fe8cd34a54788d06a13de7c96e1448eae041744568","urls":["bzz-raw://6bf07369fee84b74edd61c8eb08bf71e3f4fdbb6ad24061996b4e2bfd42f3f69","dweb:/ipfs/QmQhyYedzf8GtTc51495Lek1rZBQ6nigrGFXUpwHhN3RLa"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":27}

View File

@@ -1 +1 @@
{"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdCheats.sol\":\"StdCheats\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdCheats.sol\":{\"keccak256\":\"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e\",\"dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]},\"lib/forge-std/src/console.sol\":{\"keccak256\":\"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57\",\"dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP\"]},\"lib/forge-std/src/console2.sol\":{\"keccak256\":\"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d\",\"dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdCheats.sol":"StdCheats"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdCheats.sol":{"keccak256":"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c","urls":["bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e","dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"},"lib/forge-std/src/console.sol":{"keccak256":"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5","urls":["bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57","dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP"],"license":"MIT"},"lib/forge-std/src/console2.sol":{"keccak256":"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f","urls":["bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d","dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ"],"license":"MIT"}},"version":1},"id":27} {"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdCheats.sol\":\"StdCheats\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdCheats.sol\":{\"keccak256\":\"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e\",\"dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]},\"lib/forge-std/src/console.sol\":{\"keccak256\":\"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57\",\"dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP\"]},\"lib/forge-std/src/console2.sol\":{\"keccak256\":\"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d\",\"dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdCheats.sol":"StdCheats"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdCheats.sol":{"keccak256":"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c","urls":["bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e","dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"},"lib/forge-std/src/console.sol":{"keccak256":"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5","urls":["bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57","dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP"],"license":"MIT"},"lib/forge-std/src/console2.sol":{"keccak256":"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f","urls":["bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d","dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ"],"license":"MIT"}},"version":1},"id":28}

View File

@@ -1 +1 @@
{"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdCheats.sol\":\"StdCheatsSafe\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdCheats.sol\":{\"keccak256\":\"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e\",\"dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]},\"lib/forge-std/src/console.sol\":{\"keccak256\":\"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57\",\"dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP\"]},\"lib/forge-std/src/console2.sol\":{\"keccak256\":\"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d\",\"dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdCheats.sol":"StdCheatsSafe"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdCheats.sol":{"keccak256":"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c","urls":["bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e","dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"},"lib/forge-std/src/console.sol":{"keccak256":"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5","urls":["bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57","dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP"],"license":"MIT"},"lib/forge-std/src/console2.sol":{"keccak256":"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f","urls":["bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d","dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ"],"license":"MIT"}},"version":1},"id":27} {"abi":[],"bytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"deployedBytecode":{"object":"0x","sourceMap":"","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdCheats.sol\":\"StdCheatsSafe\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdCheats.sol\":{\"keccak256\":\"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e\",\"dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i\"]},\"lib/forge-std/src/StdStorage.sol\":{\"keccak256\":\"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616\",\"dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]},\"lib/forge-std/src/console.sol\":{\"keccak256\":\"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57\",\"dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP\"]},\"lib/forge-std/src/console2.sol\":{\"keccak256\":\"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d\",\"dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdCheats.sol":"StdCheatsSafe"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdCheats.sol":{"keccak256":"0x07852d61fcf2fe5e25fa66e607f52cb97eab8adaf2e3fd4cb8404eb69baee90c","urls":["bzz-raw://ed97c9c7372b77a0b417c1285f631aa1396d8c3104f14b80abd559f305d67d1e","dweb:/ipfs/QmeHLpi3g9XKLT8z76AF5ofwrXQm2yxPDpWztCZ2wPDW6i"],"license":"MIT"},"lib/forge-std/src/StdStorage.sol":{"keccak256":"0xddd9f444525fe3b2db77df55bde598676784b13bd19ead1d19b95802de0eacdc","urls":["bzz-raw://53770fa34bf0d75fd2946b71335ce6e6001053595e6dd78e7af9baf7a5270616","dweb:/ipfs/QmVvfuJi928Hw6i44oUArYeAP8Pst1bvQvUeJ3CTdh1yUZ"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"},"lib/forge-std/src/console.sol":{"keccak256":"0x4bbf47eb762cef93729d6ef15e78789957147039b113e5d4df48e3d3fd16d0f5","urls":["bzz-raw://af9e3a7c3d82fb5b10b57ca4d1a82f2acbef80c077f6f6ef0cc0187c7bfd9f57","dweb:/ipfs/QmR9VzmnBDJpgiDP6CHT6truehukF9HpYvuP6kRiJbDwPP"],"license":"MIT"},"lib/forge-std/src/console2.sol":{"keccak256":"0x3b8fe79f48f065a4e4d35362171304a33784c3a90febae5f2787805a438de12f","urls":["bzz-raw://61de63af08803549299e68b6e6e88d40f3c5afac450e4ee0a228c66a61ba003d","dweb:/ipfs/QmWVoQ5rrVxnczD4ZZoPbD4PC9Z3uExJtzjD4awTqd14MZ"],"license":"MIT"}},"version":1},"id":28}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"abi":[],"bytecode":{"object":"0x6080806040523460175760399081601c823930815050f35b5f80fdfe5f80fdfea2646970667358221220cf0d48da6f94a91b03479d3fa188b1663f392149dea15a517ab7bbfa9ae955d464736f6c634300081e0033","sourceMap":"610:9052:31:-:0;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x5f80fdfea2646970667358221220cf0d48da6f94a91b03479d3fa188b1663f392149dea15a517ab7bbfa9ae955d464736f6c634300081e0033","sourceMap":"610:9052:31:-:0;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdJson.sol\":\"stdJson\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@ensdomains/=node_modules/@ensdomains/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdJson.sol\":{\"keccak256\":\"0x9de30197a56fe90c443948c3feeb20e9a29e0e9c0b8fa893e8ac4c1344acd589\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://444783bd32a8abfd3fbcf16c5d1cdccef5608b2a9cfddd789fa1b045b077ed2a\",\"dweb:/ipfs/QmY94NxHDFW1Knxs9GcgFhq2QZQpRXgor4NMamKQ9CCVyp\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@ensdomains/=node_modules/@ensdomains/","@openzeppelin/=node_modules/@openzeppelin/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdJson.sol":"stdJson"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdJson.sol":{"keccak256":"0x9de30197a56fe90c443948c3feeb20e9a29e0e9c0b8fa893e8ac4c1344acd589","urls":["bzz-raw://444783bd32a8abfd3fbcf16c5d1cdccef5608b2a9cfddd789fa1b045b077ed2a","dweb:/ipfs/QmY94NxHDFW1Knxs9GcgFhq2QZQpRXgor4NMamKQ9CCVyp"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":31} {"abi":[],"bytecode":{"object":"0x6080806040523460175760399081601c823930815050f35b5f80fdfe5f80fdfea2646970667358221220eb970f2af120600227e71c7987828310a9cbdd34aef4186c7a9dbb1ae6ed54da64736f6c634300081e0033","sourceMap":"610:9052:32:-:0;;;;;;;;;;;;;;;;;;;;;","linkReferences":{}},"deployedBytecode":{"object":"0x5f80fdfea2646970667358221220eb970f2af120600227e71c7987828310a9cbdd34aef4186c7a9dbb1ae6ed54da64736f6c634300081e0033","sourceMap":"610:9052:32:-:0;;","linkReferences":{}},"methodIdentifiers":{},"rawMetadata":"{\"compiler\":{\"version\":\"0.8.30+commit.73712a01\"},\"language\":\"Solidity\",\"output\":{\"abi\":[],\"devdoc\":{\"kind\":\"dev\",\"methods\":{},\"version\":1},\"userdoc\":{\"kind\":\"user\",\"methods\":{},\"version\":1}},\"settings\":{\"compilationTarget\":{\"lib/forge-std/src/StdJson.sol\":\"stdJson\"},\"evmVersion\":\"prague\",\"libraries\":{},\"metadata\":{\"bytecodeHash\":\"ipfs\"},\"optimizer\":{\"enabled\":true,\"runs\":200},\"remappings\":[\":@arbitrum/=node_modules/@arbitrum/\",\":@chainlink/=node_modules/@chainlink/\",\":@ensdomains/=node_modules/@ensdomains/\",\":@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/\",\":@offchainlabs/=node_modules/@offchainlabs/\",\":@openzeppelin/=node_modules/@openzeppelin/\",\":@scroll-tech/=node_modules/@scroll-tech/\",\":@zksync/=node_modules/@zksync/\",\":forge-std/=lib/forge-std/src/\",\":hardhat/=node_modules/hardhat/\",\":solady/=node_modules/solady/\"],\"viaIR\":true},\"sources\":{\"lib/forge-std/src/StdJson.sol\":{\"keccak256\":\"0x9de30197a56fe90c443948c3feeb20e9a29e0e9c0b8fa893e8ac4c1344acd589\",\"license\":\"MIT\",\"urls\":[\"bzz-raw://444783bd32a8abfd3fbcf16c5d1cdccef5608b2a9cfddd789fa1b045b077ed2a\",\"dweb:/ipfs/QmY94NxHDFW1Knxs9GcgFhq2QZQpRXgor4NMamKQ9CCVyp\"]},\"lib/forge-std/src/Vm.sol\":{\"keccak256\":\"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a\",\"license\":\"MIT OR Apache-2.0\",\"urls\":[\"bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2\",\"dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV\"]}},\"version\":1}","metadata":{"compiler":{"version":"0.8.30+commit.73712a01"},"language":"Solidity","output":{"abi":[],"devdoc":{"kind":"dev","methods":{},"version":1},"userdoc":{"kind":"user","methods":{},"version":1}},"settings":{"remappings":["@arbitrum/=node_modules/@arbitrum/","@chainlink/=node_modules/@chainlink/","@ensdomains/=node_modules/@ensdomains/","@eth-optimism/=node_modules/@chainlink/contracts/node_modules/@eth-optimism/","@offchainlabs/=node_modules/@offchainlabs/","@openzeppelin/=node_modules/@openzeppelin/","@scroll-tech/=node_modules/@scroll-tech/","@zksync/=node_modules/@zksync/","forge-std/=lib/forge-std/src/","hardhat/=node_modules/hardhat/","solady/=node_modules/solady/"],"optimizer":{"enabled":true,"runs":200},"metadata":{"bytecodeHash":"ipfs"},"compilationTarget":{"lib/forge-std/src/StdJson.sol":"stdJson"},"evmVersion":"prague","libraries":{},"viaIR":true},"sources":{"lib/forge-std/src/StdJson.sol":{"keccak256":"0x9de30197a56fe90c443948c3feeb20e9a29e0e9c0b8fa893e8ac4c1344acd589","urls":["bzz-raw://444783bd32a8abfd3fbcf16c5d1cdccef5608b2a9cfddd789fa1b045b077ed2a","dweb:/ipfs/QmY94NxHDFW1Knxs9GcgFhq2QZQpRXgor4NMamKQ9CCVyp"],"license":"MIT"},"lib/forge-std/src/Vm.sol":{"keccak256":"0x1f3cfde19cafbd145904bfb00581a10ca7667186276e8c91dc2943ec559de88a","urls":["bzz-raw://bdf9afa0df475e5ea0aa1f5feb27987499051a1a85a9177d3d01e131ff0f1af2","dweb:/ipfs/QmdQfAdeU4PtQSHs1mMwoEUpdFfbrgRdJuhVXeaxeb5dxV"],"license":"MIT OR Apache-2.0"}},"version":1},"id":32}

Some files were not shown because too many files have changed in this diff Show More