commit
This commit is contained in:
48
.gitignore
vendored
Normal file
48
.gitignore
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
# Dependencies
|
||||
node_modules/
|
||||
|
||||
# Production build
|
||||
dist/
|
||||
build/
|
||||
|
||||
# Hardhat files
|
||||
cache/
|
||||
artifacts/
|
||||
typechain-types/
|
||||
|
||||
# Hardhat Ignition default folder for deployments
|
||||
ignition/deployments/
|
||||
|
||||
# Environment variables
|
||||
.env
|
||||
.env.local
|
||||
.env.*.local
|
||||
|
||||
# Log files
|
||||
*.log
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
|
||||
# Coverage
|
||||
coverage/
|
||||
coverage.json
|
||||
*.lcov
|
||||
|
||||
# IDE
|
||||
.idea/
|
||||
.vscode/
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Gas reports
|
||||
gas-report.txt
|
||||
|
||||
# Misc
|
||||
*.tsbuildinfo
|
||||
.eslintcache
|
||||
3
.gitmodules
vendored
Normal file
3
.gitmodules
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
[submodule "lib/forge-std"]
|
||||
path = lib/forge-std
|
||||
url = https://github.com/foundry-rs/forge-std
|
||||
2763
.openzeppelin/unknown-421614.json
Normal file
2763
.openzeppelin/unknown-421614.json
Normal file
File diff suppressed because it is too large
Load Diff
346
README.md
Normal file
346
README.md
Normal file
@@ -0,0 +1,346 @@
|
||||
# Hardhat2 + Foundry EVM 开发框架
|
||||
|
||||
这是一个将 Hardhat 与 Foundry 无缝整合的 Solidity 开发框架,既保留了 Hardhat 的插件生态(部署、验证、脚本执行、TypeScript 开发体验),也利用 Foundry 的高速 EVM、测试与脚本执行能力。适用于复杂合约开发、测试驱动开发 (TDD)、多环境部署与高级调试需求。
|
||||
|
||||
## create2 factory
|
||||
框架通过魔改 hardhdat-upgrade 包实现可以指定各条链的factory合约地址使用create2部署地址一样的合约。
|
||||
注意:调用factory部署合约时需要确定你的地址拥有factory合约的admin权限,否则会失败。
|
||||
|
||||
可升级合约使用方式(想要使用factory部署,在调用upgrades.deployProxy时指定create2Factory配置即可。否则不指定create2Factory配置就是非create2 factory模式进行部署):
|
||||
```bash
|
||||
const ContractFactory = await ethers.getContractFactory(CONTRACT_NAME);
|
||||
const INIT_ARGS: any[] = [];
|
||||
|
||||
const create2Config = {
|
||||
address: FACTORY_ADDRESS,
|
||||
salt: proxySalt, // 代理合约的 salt
|
||||
implSalt: implSalt, // 实现合约的 salt
|
||||
deployImpl: true, // 实现合约也用 CREATE2 部署
|
||||
};
|
||||
|
||||
const contract = await upgrades.deployProxy(
|
||||
ContractFactory,
|
||||
INIT_ARGS,
|
||||
{
|
||||
initializer: 'initialize',
|
||||
kind: 'uups',
|
||||
...( { create2Factory: create2Config } as any ),
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
不可升级合约使用方式(不想使用factory部署,直接调用Yourcontract.deploy即可):
|
||||
```bash
|
||||
const ContractFactory = await ethers.getContractFactory('YourContract');
|
||||
const bytecode = ContractFactory.bytecode;
|
||||
const constructorArgs = ethers.AbiCoder.defaultAbiCoder().encode(
|
||||
['uint256'], // 构造函数参数类型
|
||||
[123] // 构造函数参数值
|
||||
);
|
||||
|
||||
const initCode = ethers.concat([bytecode, constructorArgs]);
|
||||
|
||||
const factoryContract = await ethers.getContractAt(
|
||||
['function deploy(bytes32 salt, bytes memory initCode, bytes memory data, uint256 create2ForwardValue, uint256 callForwardValue) external payable returns (address)'],
|
||||
FACTORY_ADDRESS
|
||||
);
|
||||
|
||||
const tx = await factoryContract.deploy(
|
||||
salt,
|
||||
initCode,
|
||||
'0x', // 部署后不需要额外调用
|
||||
0, // create2ForwardValue
|
||||
0 // callForwardValue
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
同时本项目集成了 check / sync / validate / parse 四个核心命令,构建出一套完整的智能合约升级与安全验证流程。
|
||||
额外带有修复hardhat-config.ts文件引用错误的功能 fix(使用evm-hardhat-foundry包部署的框架则不会用到此功能,以往项目可能会用到,例如错误引用:import { HardhatUserConfig } from "hardhat/config";)
|
||||
|
||||
## 功能特性
|
||||
功能一: 字节码检查(check)
|
||||
功能二: 合约状态同步(sync)
|
||||
功能三: 升级验证(validate)
|
||||
功能四: Calldata解析(parse)
|
||||
功能五: hardhat-config.ts文件修复(fix)
|
||||
|
||||
### 功能一: 字节码检查(check)
|
||||
- ✅ 检查链下合约代码和链上合约代码是否一致
|
||||
- ✅ 支持检查单个合约、指定网络或所有合约
|
||||
- ✅ 智能识别 Constructor 参数差异和 Immutable 变量差异
|
||||
- ✅ 自动移除元数据进行比较
|
||||
- ✅ 生成详细的 JSON 报告
|
||||
- ✅ 支持增量更新报告
|
||||
|
||||
#### 1. 修改配置文件
|
||||
|
||||
在项目根目录创建 `contractInfo.json` 文件:
|
||||
|
||||
```json
|
||||
{
|
||||
"eth": {
|
||||
"Vault": "0x80aaf2e4636c510e067a5d300d8bafd48027addf",
|
||||
"VaultCrossChainRelay": "0x060194eec4556096baaabd6bf553d2658d6a66ab"
|
||||
},
|
||||
"bsc": {
|
||||
"Vault": "0x2cb7d2603a5f43b9fe79e98f09fe3eec40b6765d",
|
||||
"VaultCrossChainRelay": "0x23ae3a565e0896866e7725fe6d49fd777359c162"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
格式说明:
|
||||
- 第一层 key 是网络名称(必须与 `hardhat.config.js` 中的网络名称一致)
|
||||
- 第二层 key 是合约名称(必须与编译的合约名称一致)
|
||||
- value 是合约地址
|
||||
|
||||
#### 2. 配置 Hardhat
|
||||
|
||||
确保 `hardhat.config.js` 中配置了相应的网络:
|
||||
|
||||
```javascript
|
||||
module.exports = {
|
||||
networks: {
|
||||
eth: {
|
||||
url: "https://eth-mainnet.g.alchemy.com/v2/YOUR-API-KEY",
|
||||
},
|
||||
bsc: {
|
||||
url: "https://bsc-dataseed.binance.org/",
|
||||
}
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
#### 3. 使用工具
|
||||
|
||||
##### 📋 查看帮助
|
||||
|
||||
```bash
|
||||
npx gate-tool --help
|
||||
```
|
||||
|
||||
##### 🔍 字节码检查
|
||||
|
||||
```bash
|
||||
# 检查所有合约(推荐)
|
||||
npx gate-tool check
|
||||
|
||||
# 检查指定合约
|
||||
npx gate-tool check --contract Vault
|
||||
|
||||
# 检查指定网络
|
||||
npx gate-tool check --network eth
|
||||
|
||||
# 指定配置文件路径
|
||||
npx gate-tool check --config ./config/contracts.json
|
||||
|
||||
# 指定输出报告路径
|
||||
npx gate-tool check --output ./reports/result.json
|
||||
```
|
||||
|
||||
### 功能二: 合约状态同步(sync)
|
||||
- ✅ 同步链上合约状态到本地 .openzeppelin 文件
|
||||
- ✅ 自动读取链上实现合约地址
|
||||
- ✅ 获取并更新存储布局信息
|
||||
|
||||
#### 1. 同步链上合约状态
|
||||
|
||||
当合约通过 calldata 方式由其他人(如多签钱包)执行升级后,本地的 `.openzeppelin` 文件不会自动更新。使用此命令可以从链上读取最新状态并更新本地文件。
|
||||
|
||||
```bash
|
||||
# 同步合约状态(推荐)
|
||||
npx gate-tool sync \
|
||||
--proxy 0x1234... \
|
||||
--contract CounterUUPS \
|
||||
--network sepolia
|
||||
```
|
||||
|
||||
### 功能三: 升级验证(validate)
|
||||
- ✅ 验证合约升级的安全性
|
||||
- ✅ 检查存储布局兼容性
|
||||
- ✅ 自动部署新实现合约
|
||||
- ✅ 生成 upgradeToAndCall 的 calldata
|
||||
- ✅ 支持同一合约和不同合约的升级模式
|
||||
|
||||
#### 1. 验证升级安全性并生成 calldata
|
||||
|
||||
验证合约升级的安全性,并生成 `upgradeToAndCall` 的 calldata。
|
||||
|
||||
```bash
|
||||
# 不同合约升级(从 CounterUUPS 升级到 CounterUUPSV2)
|
||||
npx gate-tool validate \
|
||||
--proxy 0x1234... \
|
||||
--old CounterUUPS \
|
||||
--new CounterUUPSV2 \
|
||||
--network sepolia
|
||||
|
||||
# 同一合约升级(修改现有合约后升级)(推荐)
|
||||
npx gate-tool validate \
|
||||
--proxy 0x1234... \
|
||||
--old CounterUUPS \
|
||||
--new CounterUUPS \
|
||||
--network sepolia
|
||||
|
||||
# 指定输出文件路径
|
||||
npx gate-tool validate \
|
||||
--proxy 0x1234... \
|
||||
--old CounterUUPS \
|
||||
--new CounterUUPSV2 \
|
||||
--network sepolia \
|
||||
--output ./upgrade-info.json
|
||||
```
|
||||
|
||||
**注意:** `validate` 命令会在链上部署新的实现合约(仅用于验证),但不会升级代理合约。请使用生成的 calldata 通过多签钱包执行升级。
|
||||
|
||||
### 功能四: Calldata 解析(parse)
|
||||
- ✅ 解析 EVM calldata,显示函数名称和参数
|
||||
- ✅ 支持从 Hardhat artifacts 自动查找 ABI
|
||||
- ✅ 支持指定自定义 ABI 文件路径
|
||||
- ✅ 支持直接提供 ABI 数组
|
||||
- ✅ 支持批量解析多个 calldata
|
||||
- ✅ 友好的彩色输出和 JSON 导出
|
||||
|
||||
#### 1. 解析 Calldata
|
||||
|
||||
解析 EVM calldata,将其转换为人类可读的函数调用信息。
|
||||
|
||||
```bash
|
||||
# 从 JSON 文件单个或批量读取(推荐)
|
||||
npx gate-tool parse --input parseCalldata.example.json --output results.json
|
||||
|
||||
# 直接从命令行参数(使用合约名称从 artifacts 查找 ABI)
|
||||
npx gate-tool parse \
|
||||
--to 0x5FbDB2315678afecb367f032d93F642f64180aa3 \
|
||||
--contract Counter \
|
||||
--calldata 0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000064
|
||||
|
||||
# 使用自定义 ABI 文件
|
||||
npx gate-tool parse \
|
||||
--to 0x1234... \
|
||||
--abi-path ./custom-abi/MyContract.json \
|
||||
--calldata 0x...
|
||||
|
||||
**输入文件格式示例:**
|
||||
|
||||
```json
|
||||
{
|
||||
"to": "0x5FbDB2315678afecb367f032d93F642f64180aa3",
|
||||
"contractName": "Counter",
|
||||
"calldata": "0x3fb5c1cb0000000000000000000000000000000000000000000000000000000000000064"
|
||||
}
|
||||
```
|
||||
|
||||
**批量解析格式(数组 包含三种形式):**
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"to": "0x...",
|
||||
"contractName": "Counter",
|
||||
"calldata": "0x..."
|
||||
},
|
||||
{
|
||||
"to": "0x...",
|
||||
"abiPath": "./abi.json",
|
||||
"calldata": "0x..."
|
||||
},
|
||||
{
|
||||
"": "0x...",
|
||||
"abi": [
|
||||
{
|
||||
"inputs": [
|
||||
{"name": "spender", "type": "address"},
|
||||
{"name": "amount", "type": "uint256"}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [{"name": "", "type": "bool"}],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
],
|
||||
"calldata": "0x..."
|
||||
}
|
||||
]
|
||||
```
|
||||
|
||||
支持三种 ABI 来源方式:
|
||||
1. **contractName** - 从 Hardhat artifacts 自动查找(需要先编译合约)
|
||||
2. **abiPath** - 指定 ABI 文件路径
|
||||
3. **abi** - 直接在 JSON 中提供 ABI 数组
|
||||
|
||||
### 功能五: 配置修复(fix)
|
||||
- ✅ 自动检测 Hardhat 配置文件的兼容性问题
|
||||
- ✅ 智能修复 ESM 模块导入错误
|
||||
- ✅ 交互式确认修复操作
|
||||
- ✅ 自动备份原配置文件
|
||||
- ✅ 支持仅检查模式
|
||||
|
||||
#### 1. 配置修复(推荐首次使用)
|
||||
|
||||
如果在使用过程中遇到 Hardhat 配置导入错误,可以使用 `fix` 命令自动修复:
|
||||
|
||||
```bash
|
||||
# 自动检测并修复配置问题(推荐 交互式)
|
||||
npx gate-tool fix
|
||||
|
||||
# 仅检查问题,不执行修复
|
||||
npx gate-tool fix --check
|
||||
|
||||
# 跳过确认,直接修复
|
||||
npx gate-tool fix --yes
|
||||
```
|
||||
|
||||
**常见问题:**
|
||||
- `Cannot find module 'hardhat/config'` - 导入语句需要使用 `type` 关键字
|
||||
- `Did you mean to import "hardhat/config.js"?` - ESM 模块兼容性问题
|
||||
|
||||
`fix` 命令会自动将:
|
||||
```typescript
|
||||
import { HardhatUserConfig } from "hardhat/config";
|
||||
```
|
||||
修复为:
|
||||
```typescript
|
||||
import type { HardhatUserConfig } from "hardhat/config";
|
||||
```
|
||||
|
||||
## 命令选项
|
||||
|
||||
### check 命令
|
||||
|
||||
| 选项 | 简写 | 说明 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `--contract <name>` | `-c` | 指定要检查的合约名称 | - |
|
||||
| `--network <name>` | `-n` | 指定要检查的网络名称 | - |
|
||||
| `--config <path>` | - | 指定配置文件路径 | `./contractInfo.json` |
|
||||
| `--output <path>` | `-o` | 指定输出报告文件路径 | `./bytecode-check-report.json` |
|
||||
|
||||
### sync 命令
|
||||
|
||||
| 选项 | 简写 | 说明 | 必需 |
|
||||
|------|------|------|------|
|
||||
| `--proxy <address>` | - | 代理合约地址 | ✅ |
|
||||
| `--contract <name>` | - | 合约名称 | ✅ |
|
||||
| `--network <name>` | `-n` | 网络名称 | - |
|
||||
|
||||
### validate 命令
|
||||
|
||||
| 选项 | 简写 | 说明 | 必需 |
|
||||
|------|------|------|------|
|
||||
| `--proxy <address>` | - | 代理合约地址 | ✅ |
|
||||
| `--old <name>` | - | 旧合约名称 | ✅ |
|
||||
| `--new <name>` | - | 新合约名称 | ✅ |
|
||||
| `--network <name>` | `-n` | 网络名称 | - |
|
||||
| `--output <path>` | `-o` | 输出文件路径 | `./upgradeCalldata.json` |
|
||||
|
||||
#### parse 命令
|
||||
|
||||
| 选项 | 简写 | 说明 | 默认值 |
|
||||
|------|------|------|--------|
|
||||
| `--input <path>` | `-i` | 输入 JSON 文件路径 | - |
|
||||
| `--to <address>` | - | 目标合约地址(命令行模式) | - |
|
||||
| `--calldata <data>` | - | Calldata 十六进制数据(命令行模式) | - |
|
||||
| `--contract <name>` | `-c` | 合约名称(从 artifacts 查找 ABI) | - |
|
||||
| `--abi-path <path>` | - | 自定义 ABI 文件路径 | - |
|
||||
| `--output <path>` | `-o` | 输出 JSON 文件路径 | - |
|
||||
**ABI 来源优先级**:直接提供的 abi > abiPath > contractName
|
||||
13
abis/Address.json
Normal file
13
abis/Address.json
Normal file
@@ -0,0 +1,13 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
}
|
||||
]
|
||||
1273
abis/Configurator.json
Normal file
1273
abis/Configurator.json
Normal file
File diff suppressed because it is too large
Load Diff
105
abis/ConfiguratorStorage.json
Normal file
105
abis/ConfiguratorStorage.json
Normal file
@@ -0,0 +1,105 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "configuratorParams",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "baseToken",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "baseTokenPriceFeed",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "supplyKink",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "supplyPerYearInterestRateSlopeLow",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "supplyPerYearInterestRateSlopeHigh",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "supplyPerYearInterestRateBase",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "borrowKink",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "borrowPerYearInterestRateSlopeLow",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "borrowPerYearInterestRateSlopeHigh",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "borrowPerYearInterestRateBase",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "storeFrontPriceFactor",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "trackingIndexScale",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint104",
|
||||
"name": "baseBorrowMin",
|
||||
"type": "uint104"
|
||||
},
|
||||
{
|
||||
"internalType": "uint104",
|
||||
"name": "targetReserves",
|
||||
"type": "uint104"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "factory",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
25
abis/ContextUpgradeable.json
Normal file
25
abis/ContextUpgradeable.json
Normal file
@@ -0,0 +1,25 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
67
abis/ERC1967Proxy.json
Normal file
67
abis/ERC1967Proxy.json
Normal file
@@ -0,0 +1,67 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "_data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"stateMutability": "payable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"stateMutability": "payable",
|
||||
"type": "fallback"
|
||||
}
|
||||
]
|
||||
40
abis/ERC1967Utils.json
Normal file
40
abis/ERC1967Utils.json
Normal file
@@ -0,0 +1,40 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "admin",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidAdmin",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "beacon",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidBeacon",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
}
|
||||
]
|
||||
310
abis/ERC20.json
Normal file
310
abis/ERC20.json
Normal file
@@ -0,0 +1,310 @@
|
||||
[
|
||||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"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": 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"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
333
abis/ERC20Upgradeable.json
Normal file
333
abis/ERC20Upgradeable.json
Normal file
@@ -0,0 +1,333 @@
|
||||
[
|
||||
{
|
||||
"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": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"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": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
818
abis/ERC4626Upgradeable.json
Normal file
818
abis/ERC4626Upgradeable.json
Normal file
@@ -0,0 +1,818 @@
|
||||
[
|
||||
{
|
||||
"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": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "max",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC4626ExceededMaxDeposit",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "max",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC4626ExceededMaxMint",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "max",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC4626ExceededMaxRedeem",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "max",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC4626ExceededMaxWithdraw",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "SafeERC20FailedOperation",
|
||||
"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": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Deposit",
|
||||
"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": "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": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Withdraw",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"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": [],
|
||||
"name": "asset",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "convertToAssets",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "convertToShares",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "deposit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxDeposit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxMint",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxRedeem",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxWithdraw",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "mint",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewDeposit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewMint",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewRedeem",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewWithdraw",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "redeem",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalAssets",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
39
abis/Errors.json
Normal file
39
abis/Errors.json
Normal file
@@ -0,0 +1,39 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedDeployment",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "needed",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "InsufficientBalance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "MissingPrecompile",
|
||||
"type": "error"
|
||||
}
|
||||
]
|
||||
15
abis/IBeacon.json
Normal file
15
abis/IBeacon.json
Normal file
@@ -0,0 +1,15 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "implementation",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
104
abis/IERC1155Errors.json
Normal file
104
abis/IERC1155Errors.json
Normal file
@@ -0,0 +1,104 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "needed",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC1155InsufficientBalance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "approver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1155InvalidApprover",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "idsLength",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "valuesLength",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC1155InvalidArrayLength",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1155InvalidOperator",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1155InvalidReceiver",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1155InvalidSender",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1155MissingApprovalForAll",
|
||||
"type": "error"
|
||||
}
|
||||
]
|
||||
373
abis/IERC1363.json
Normal file
373
abis/IERC1363.json
Normal file
@@ -0,0 +1,373 @@
|
||||
[
|
||||
{
|
||||
"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": 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"
|
||||
},
|
||||
{
|
||||
"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": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approveAndCall",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "approveAndCall",
|
||||
"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": "bytes4",
|
||||
"name": "interfaceId",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"name": "supportsInterface",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"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": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferAndCall",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "transferAndCall",
|
||||
"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": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "transferFromAndCall",
|
||||
"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": "transferFromAndCall",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
21
abis/IERC165.json
Normal file
21
abis/IERC165.json
Normal file
@@ -0,0 +1,21 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes4",
|
||||
"name": "interfaceId",
|
||||
"type": "bytes4"
|
||||
}
|
||||
],
|
||||
"name": "supportsInterface",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
15
abis/IERC1822Proxiable.json
Normal file
15
abis/IERC1822Proxiable.json
Normal file
@@ -0,0 +1,15 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
47
abis/IERC1967.json
Normal file
47
abis/IERC1967.json
Normal file
@@ -0,0 +1,47 @@
|
||||
[
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "previousAdmin",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "newAdmin",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AdminChanged",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "beacon",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "BeaconUpgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
185
abis/IERC20.json
Normal file
185
abis/IERC20.json
Normal file
@@ -0,0 +1,185 @@
|
||||
[
|
||||
{
|
||||
"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": 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"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "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"
|
||||
}
|
||||
]
|
||||
88
abis/IERC20Errors.json
Normal file
88
abis/IERC20Errors.json
Normal file
@@ -0,0 +1,88 @@
|
||||
[
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
224
abis/IERC20Metadata.json
Normal file
224
abis/IERC20Metadata.json
Normal file
@@ -0,0 +1,224 @@
|
||||
[
|
||||
{
|
||||
"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": 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"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
614
abis/IERC4626.json
Normal file
614
abis/IERC4626.json
Normal file
@@ -0,0 +1,614 @@
|
||||
[
|
||||
{
|
||||
"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": true,
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Deposit",
|
||||
"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": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Withdraw",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"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": [],
|
||||
"name": "asset",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "assetTokenAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "convertToAssets",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "convertToShares",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "deposit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxDeposit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxAssets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxMint",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxShares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxRedeem",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxShares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "maxWithdraw",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxAssets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "mint",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewDeposit",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewMint",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewRedeem",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "previewWithdraw",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "redeem",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalAssets",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "totalManagedAssets",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "assets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "shares",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
105
abis/IERC721Errors.json
Normal file
105
abis/IERC721Errors.json
Normal file
@@ -0,0 +1,105 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC721IncorrectOwner",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC721InsufficientApproval",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "approver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC721InvalidApprover",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "operator",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC721InvalidOperator",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC721InvalidOwner",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC721InvalidReceiver",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC721InvalidSender",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "tokenId",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC721NonexistentToken",
|
||||
"type": "error"
|
||||
}
|
||||
]
|
||||
619
abis/ILending.json
Normal file
619
abis/ILending.json
Normal file
@@ -0,0 +1,619 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "BorrowTooSmall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InsufficientBalance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InsufficientCollateral",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InsufficientReserves",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidLiquidationFactor",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotLiquidatable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "SupplyCapExceeded",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Unauthorized",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "absorber",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "borrower",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "collateralAbsorbed",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "usdValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "AbsorbCollateral",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "absorber",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "borrower",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "basePaidOut",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "usdValue",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "AbsorbDebt",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "buyer",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "baseAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "collateralAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "BuyCollateral",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "dst",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Supply",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "dst",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "SupplyCollateral",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "src",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Withdraw",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "src",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "WithdrawCollateral",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "WithdrawReserves",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "borrower",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "absorb",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "absorber",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "accounts",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "absorbMultiple",
|
||||
"outputs": [],
|
||||
"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": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "borrow",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "borrowBalanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "minAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "baseAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "recipient",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "buyCollateral",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getBalance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getBorrowRate",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getCollateral",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getCollateralReserves",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getReserves",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getSupplyRate",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getUtilization",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isLiquidatable",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "baseAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "quoteCollateral",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "supply",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "supplyCollateral",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdrawCollateral",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdrawReserves",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
28
abis/IPriceFeed.json
Normal file
28
abis/IPriceFeed.json
Normal file
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "price",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
51
abis/IUSDY.json
Normal file
51
abis/IUSDY.json
Normal file
@@ -0,0 +1,51 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "burn",
|
||||
"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": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
38
abis/IYTLPToken.json
Normal file
38
abis/IYTLPToken.json
Normal file
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "burn",
|
||||
"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"
|
||||
}
|
||||
]
|
||||
104
abis/IYTPoolManager.json
Normal file
104
abis/IYTPoolManager.json
Normal file
@@ -0,0 +1,104 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_fundingAccount",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minUsdy",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minYtLP",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "addLiquidityForAccount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_maximise",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "getPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenOut",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_ytLPAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minOut",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeLiquidityForAccount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
26
abis/IYTPriceFeed.json
Normal file
26
abis/IYTPriceFeed.json
Normal file
@@ -0,0 +1,26 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_maximise",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "getPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
28
abis/IYTToken.json
Normal file
28
abis/IYTToken.json
Normal file
@@ -0,0 +1,28 @@
|
||||
[
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
213
abis/IYTVault.json
Normal file
213
abis/IYTVault.json
Normal file
@@ -0,0 +1,213 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "buyUSDY",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getMaxPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getMinPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_maximise",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "getPoolValue",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_maximise",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "getPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_usdyAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getRedemptionFeeBasisPoints",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenIn",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenOut",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_usdyAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getSwapFeeBasisPoints",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "sellUSDY",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenIn",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenOut",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "swap",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
25
abis/Initializable.json
Normal file
25
abis/Initializable.json
Normal file
@@ -0,0 +1,25 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
1442
abis/Lending.json
Normal file
1442
abis/Lending.json
Normal file
File diff suppressed because it is too large
Load Diff
107
abis/LendingFactory.json
Normal file
107
abis/LendingFactory.json
Normal file
@@ -0,0 +1,107 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"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": "lending",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "LendingDeployed",
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "deploy",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"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": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
379
abis/LendingStorage.json
Normal file
379
abis/LendingStorage.json
Normal file
@@ -0,0 +1,379 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "assetConfigs",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "asset",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "priceFeed",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "decimals",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "borrowCollateralFactor",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "liquidateCollateralFactor",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "liquidationFactor",
|
||||
"type": "uint64"
|
||||
},
|
||||
{
|
||||
"internalType": "uint128",
|
||||
"name": "supplyCap",
|
||||
"type": "uint128"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "assetList",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "baseBorrowMin",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint104",
|
||||
"name": "",
|
||||
"type": "uint104"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "baseToken",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "baseTokenPriceFeed",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "borrowIndex",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "borrowKink",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "borrowPerSecondInterestRateBase",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "borrowPerSecondInterestRateSlopeHigh",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "borrowPerSecondInterestRateSlopeLow",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "collateralReserves",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "lastAccrualTime",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "storeFrontPriceFactor",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "supplyIndex",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "supplyKink",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "supplyPerSecondInterestRateBase",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "supplyPerSecondInterestRateSlopeHigh",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "supplyPerSecondInterestRateSlopeLow",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "targetReserves",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint104",
|
||||
"name": "",
|
||||
"type": "uint104"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalBorrowBase",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint104",
|
||||
"name": "",
|
||||
"type": "uint104"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupplyBase",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint104",
|
||||
"name": "",
|
||||
"type": "uint104"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "trackingIndexScale",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint64",
|
||||
"name": "",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "userBasic",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "int104",
|
||||
"name": "principal",
|
||||
"type": "int104"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "userCollateral",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
76
abis/Ownable.json
Normal file
76
abis/Ownable.json
Normal file
@@ -0,0 +1,76 @@
|
||||
[
|
||||
{
|
||||
"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": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
99
abis/OwnableUpgradeable.json
Normal file
99
abis/OwnableUpgradeable.json
Normal file
@@ -0,0 +1,99 @@
|
||||
[
|
||||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"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"
|
||||
},
|
||||
{
|
||||
"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": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
74
abis/PausableUpgradeable.json
Normal file
74
abis/PausableUpgradeable.json
Normal file
@@ -0,0 +1,74 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "EnforcedPause",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ExpectedPause",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Paused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Unpaused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "paused",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
6
abis/Proxy.json
Normal file
6
abis/Proxy.json
Normal file
@@ -0,0 +1,6 @@
|
||||
[
|
||||
{
|
||||
"stateMutability": "payable",
|
||||
"type": "fallback"
|
||||
}
|
||||
]
|
||||
30
abis/ReentrancyGuardUpgradeable.json
Normal file
30
abis/ReentrancyGuardUpgradeable.json
Normal file
@@ -0,0 +1,30 @@
|
||||
[
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ReentrancyGuardReentrantCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
}
|
||||
]
|
||||
56
abis/SafeCast.json
Normal file
56
abis/SafeCast.json
Normal file
@@ -0,0 +1,56 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "bits",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "value",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"name": "SafeCastOverflowedIntDowncast",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "int256",
|
||||
"name": "value",
|
||||
"type": "int256"
|
||||
}
|
||||
],
|
||||
"name": "SafeCastOverflowedIntToUint",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "bits",
|
||||
"type": "uint8"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "SafeCastOverflowedUintDowncast",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "SafeCastOverflowedUintToInt",
|
||||
"type": "error"
|
||||
}
|
||||
]
|
||||
34
abis/SafeERC20.json
Normal file
34
abis/SafeERC20.json
Normal file
@@ -0,0 +1,34 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "currentAllowance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "requestedDecrease",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "SafeERC20FailedDecreaseAllowance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "SafeERC20FailedOperation",
|
||||
"type": "error"
|
||||
}
|
||||
]
|
||||
636
abis/USDY.json
Normal file
636
abis/USDY.json
Normal file
@@ -0,0 +1,636 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "allowance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "needed",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InsufficientAllowance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "needed",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InsufficientBalance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "approver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidApprover",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidReceiver",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidSender",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidSpender",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Forbidden",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidVault",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableInvalidOwner",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableUnauthorizedAccount",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UUPSUnauthorizedCallContext",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "slot",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "UUPSUnsupportedProxiableUUID",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "previousOwner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "VaultAdded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "VaultRemoved",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UPGRADE_INTERFACE_VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "addVault",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "burn",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "mint",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeVault",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "upgradeToAndCall",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "vaults",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
130
abis/UUPSUpgradeable.json
Normal file
130
abis/UUPSUpgradeable.json
Normal file
@@ -0,0 +1,130 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UUPSUnauthorizedCallContext",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "slot",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "UUPSUnsupportedProxiableUUID",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UPGRADE_INTERFACE_VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "upgradeToAndCall",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
566
abis/WUSD.json
Normal file
566
abis/WUSD.json
Normal file
@@ -0,0 +1,566 @@
|
||||
[
|
||||
{
|
||||
"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"
|
||||
}
|
||||
]
|
||||
900
abis/YTAssetFactory.json
Normal file
900
abis/YTAssetFactory.json
Normal file
@@ -0,0 +1,900 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidAddress",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidHardCap",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableInvalidOwner",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableUnauthorizedAccount",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UUPSUnauthorizedCallContext",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "slot",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "UUPSUnsupportedProxiableUUID",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "VaultNotExists",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "newDefaultHardCap",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "DefaultHardCapSet",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "newHardCap",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "HardCapSet",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "redemptionTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "NextRedemptionTimeSet",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "previousOwner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "wusdPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "ytPrice",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "PricesUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "manager",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "string",
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "hardCap",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "index",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "VaultCreated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "VaultImplementationUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UPGRADE_INTERFACE_VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "allVaults",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "_symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_manager",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_hardCap",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_wusd",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_redemptionTime",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_initialWusdPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_initialYtPrice",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "createVault",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string[]",
|
||||
"name": "_names",
|
||||
"type": "string[]"
|
||||
},
|
||||
{
|
||||
"internalType": "string[]",
|
||||
"name": "_symbols",
|
||||
"type": "string[]"
|
||||
},
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_managers",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_hardCaps",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_wusd",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_redemptionTimes",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_initialWusdPrices",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_initialYtPrices",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "createVaultBatch",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "vaults",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "defaultHardCap",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getAllVaults",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getVaultCount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getVaultInfo",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "exists",
|
||||
"type": "bool"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "totalAssets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "idleAssets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "managedAssets",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "totalSupply",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "hardCap",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "wusdPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "ytPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "nextRedemptionTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_start",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_end",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "getVaults",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "vaults",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vaultImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_defaultHardCap",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isVault",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "pauseVault",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_vaults",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "pauseVaultBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_defaultHardCap",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setDefaultHardCap",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_hardCap",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setHardCap",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_vaults",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_hardCaps",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "setHardCapBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_newImplementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setVaultImplementation",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_manager",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setVaultManager",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_nextRedemptionTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setVaultNextRedemptionTime",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_vaults",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_nextRedemptionTime",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setVaultNextRedemptionTimeBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "unpauseVault",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_vaults",
|
||||
"type": "address[]"
|
||||
}
|
||||
],
|
||||
"name": "unpauseVaultBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_wusdPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_ytPrice",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "updateVaultPrices",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_vaults",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_wusdPrices",
|
||||
"type": "uint256[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_ytPrices",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "updateVaultPricesBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "upgradeToAndCall",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_vault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_newImplementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "upgradeVault",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_vaults",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_newImplementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "upgradeVaultBatch",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "vaultImplementation",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
1132
abis/YTAssetVault.json
Normal file
1132
abis/YTAssetVault.json
Normal file
File diff suppressed because it is too large
Load Diff
621
abis/YTLPToken.json
Normal file
621
abis/YTLPToken.json
Normal file
@@ -0,0 +1,621 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "allowance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "needed",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InsufficientAllowance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "balance",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "needed",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InsufficientBalance",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "approver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidApprover",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidReceiver",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "sender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidSender",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC20InvalidSpender",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidMinter",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotMinter",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableInvalidOwner",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnableUnauthorizedAccount",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UUPSUnauthorizedCallContext",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "slot",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "UUPSUnsupportedProxiableUUID",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "minter",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "isActive",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "MinterSet",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "previousOwner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "OwnershipTransferred",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Transfer",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UPGRADE_INTERFACE_VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "allowance",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "approve",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "burn",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isMinter",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "mint",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "name",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "owner",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_minter",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_isActive",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setMinter",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "upgradeToAndCall",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
703
abis/YTPoolManager.json
Normal file
703
abis/YTPoolManager.json
Normal file
@@ -0,0 +1,703 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "CooldownNotPassed",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Forbidden",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InsufficientOutput",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidAddress",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidAmount",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidDuration",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "PrivateMode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ReentrancyGuardReentrantCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "SafeERC20FailedOperation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UUPSUnauthorizedCallContext",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "slot",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "UUPSUnsupportedProxiableUUID",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "aumInUsdy",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "ytLPSupply",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "usdyAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "mintAmount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "AddLiquidity",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "duration",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "CooldownDurationSet",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "handler",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "isActive",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "HandlerSet",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "ytLPAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "aumInUsdy",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "ytLPSupply",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "usdyAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amountOut",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "RemoveLiquidity",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "BASIS_POINTS_DIVISOR",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "MAX_COOLDOWN_DURATION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "PRICE_PRECISION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UPGRADE_INTERFACE_VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "YTLP_PRECISION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_fundingAccount",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minUsdy",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minYtLP",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "addLiquidityForAccount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "aumAddition",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "aumDeduction",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "cooldownDuration",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_maximise",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "getAumInUsdy",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_maximise",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "getPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "gov",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_ytVault",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_usdy",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_ytLP",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_cooldownDuration",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isHandler",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "lastAddedAt",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenOut",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_ytLPAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minOut",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeLiquidityForAccount",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_addition",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_deduction",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setAumAdjustment",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_duration",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setCooldownDuration",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_gov",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setGov",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_handler",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_isActive",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setHandler",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "upgradeToAndCall",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "usdy",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ytLP",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ytVault",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
603
abis/YTPriceFeed.json
Normal file
603
abis/YTPriceFeed.json
Normal file
@@ -0,0 +1,603 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Forbidden",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidAddress",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "MaxChangeTooHigh",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "PriceChangeTooLarge",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "SpreadTooHigh",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UUPSUnauthorizedCallContext",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "slot",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "UUPSUnsupportedProxiableUUID",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "keeper",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "bool",
|
||||
"name": "isActive",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "KeeperSet",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "oldPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "newPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "PriceUpdate",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "spreadBps",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "SpreadUpdate",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "BASIS_POINTS_DIVISOR",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "MAX_SPREAD_BASIS_POINTS",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "PRICE_PRECISION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UPGRADE_INTERFACE_VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_price",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "forceUpdatePrice",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getMaxPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getMinPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_maximise",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "getPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getPriceInfo",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "currentPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "cachedPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "maxPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "minPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "spread",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "gov",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_wusdAddress",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "isKeeper",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "lastPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "maxPriceChangeBps",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_keeper",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "_isActive",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"name": "setKeeper",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_maxPriceChangeBps",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setMaxPriceChangeBps",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_spreadBasisPoints",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setSpreadBasisPoints",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address[]",
|
||||
"name": "_tokens",
|
||||
"type": "address[]"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256[]",
|
||||
"name": "_spreadBasisPoints",
|
||||
"type": "uint256[]"
|
||||
}
|
||||
],
|
||||
"name": "setSpreadBasisPointsForMultiple",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_wusdPriceSource",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setWusdPriceSource",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "spreadBasisPoints",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "updatePrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "upgradeToAndCall",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "wusdAddress",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "wusdPriceSource",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
503
abis/YTRewardRouter.json
Normal file
503
abis/YTRewardRouter.json
Normal file
@@ -0,0 +1,503 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "target",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "AddressEmptyCode",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "AlreadyInitialized",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "ERC1967InvalidImplementation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ERC1967NonPayable",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "EnforcedPause",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ExpectedPause",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "FailedCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "Forbidden",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InsufficientOutput",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidAddress",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidAmount",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidInitialization",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotInitializing",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ReentrancyGuardReentrantCall",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "token",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "SafeERC20FailedOperation",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UUPSUnauthorizedCallContext",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "slot",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"name": "UUPSUnsupportedProxiableUUID",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint64",
|
||||
"name": "version",
|
||||
"type": "uint64"
|
||||
}
|
||||
],
|
||||
"name": "Initialized",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Paused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "tokenIn",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "tokenOut",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amountIn",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amountOut",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Swap",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Unpaused",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "implementation",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "Upgraded",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "UPGRADE_INTERFACE_VERSION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_token",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minUsdy",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minYtLP",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "addLiquidity",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "getAccountValue",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getYtLPPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "gov",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_usdy",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_ytLP",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_ytPoolManager",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_ytVault",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "initialize",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "pause",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "paused",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "proxiableUUID",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bytes32",
|
||||
"name": "",
|
||||
"type": "bytes32"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenOut",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_ytLPAmount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minOut",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "removeLiquidity",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenIn",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_tokenOut",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amountIn",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_minOut",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_receiver",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "swapYT",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "unpause",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newImplementation",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "bytes",
|
||||
"name": "data",
|
||||
"type": "bytes"
|
||||
}
|
||||
],
|
||||
"name": "upgradeToAndCall",
|
||||
"outputs": [],
|
||||
"stateMutability": "payable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "usdy",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ytLP",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ytPoolManager",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "ytVault",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
701
abis/YTToken.json
Normal file
701
abis/YTToken.json
Normal file
@@ -0,0 +1,701 @@
|
||||
[
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "name",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "symbol",
|
||||
"type": "string"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_priceUpdater",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "constructor"
|
||||
},
|
||||
{
|
||||
"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": "InsufficientAssets",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "IntervalTooLong",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidAmount",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidUpdater",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "InvalidYield",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "NotUpdater",
|
||||
"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": "UpdateTooFrequent",
|
||||
"type": "error"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "owner",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "spender",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "Approval",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "interval",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "MinUpdateIntervalSet",
|
||||
"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": false,
|
||||
"internalType": "uint256",
|
||||
"name": "oldPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "newPrice",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "PriceUpdated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"anonymous": false,
|
||||
"inputs": [
|
||||
{
|
||||
"indexed": true,
|
||||
"internalType": "address",
|
||||
"name": "updater",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "PriceUpdaterSet",
|
||||
"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": false,
|
||||
"internalType": "uint256",
|
||||
"name": "amount",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"indexed": false,
|
||||
"internalType": "uint256",
|
||||
"name": "timestamp",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "YieldAccumulated",
|
||||
"type": "event"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "PRICE_PRECISION",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "accumulatedYield",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"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": [],
|
||||
"name": "assetPrice",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "account",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "balanceOf",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "decimals",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint8",
|
||||
"name": "",
|
||||
"type": "uint8"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "deposit",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "getPriceInfo",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "price",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "lastUpdate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "timeSinceUpdate",
|
||||
"type": "uint256"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "totalVal",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "lastPriceUpdate",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "minUpdateInterval",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"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": "priceUpdater",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "renounceOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_interval",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "setMinUpdateInterval",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "_updater",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "setPriceUpdater",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "symbol",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "string",
|
||||
"name": "",
|
||||
"type": "string"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalAssets",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "totalSupply",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"stateMutability": "view",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transfer",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "from",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "to",
|
||||
"type": "address"
|
||||
},
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "value",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "transferFrom",
|
||||
"outputs": [
|
||||
{
|
||||
"internalType": "bool",
|
||||
"name": "",
|
||||
"type": "bool"
|
||||
}
|
||||
],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "address",
|
||||
"name": "newOwner",
|
||||
"type": "address"
|
||||
}
|
||||
],
|
||||
"name": "transferOwnership",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [],
|
||||
"name": "updatePrice",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_newYield",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "updateYield",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
},
|
||||
{
|
||||
"inputs": [
|
||||
{
|
||||
"internalType": "uint256",
|
||||
"name": "_amount",
|
||||
"type": "uint256"
|
||||
}
|
||||
],
|
||||
"name": "withdraw",
|
||||
"outputs": [],
|
||||
"stateMutability": "nonpayable",
|
||||
"type": "function"
|
||||
}
|
||||
]
|
||||
1295
abis/YTVault.json
Normal file
1295
abis/YTVault.json
Normal file
File diff suppressed because it is too large
Load Diff
1
cache_forge/solidity-files-cache.json
Normal file
1
cache_forge/solidity-files-cache.json
Normal file
File diff suppressed because one or more lines are too long
1
comet
Submodule
1
comet
Submodule
Submodule comet added at 80d38c945a
5
contractInfo.json
Normal file
5
contractInfo.json
Normal file
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"localhost": {
|
||||
"Counter": "0x5FbDB2315678afecb367f032d93F642f64180aa3"
|
||||
}
|
||||
}
|
||||
9
contracts/interfaces/IUSDY.sol
Normal file
9
contracts/interfaces/IUSDY.sol
Normal file
@@ -0,0 +1,9 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
interface IUSDY {
|
||||
function mint(address _to, uint256 _amount) external;
|
||||
function burn(address _from, uint256 _amount) external;
|
||||
function totalSupply() external view returns (uint256);
|
||||
}
|
||||
|
||||
8
contracts/interfaces/IYTLPToken.sol
Normal file
8
contracts/interfaces/IYTLPToken.sol
Normal file
@@ -0,0 +1,8 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
interface IYTLPToken {
|
||||
function mint(address _to, uint256 _amount) external;
|
||||
function burn(address _from, uint256 _amount) external;
|
||||
}
|
||||
|
||||
24
contracts/interfaces/IYTPoolManager.sol
Normal file
24
contracts/interfaces/IYTPoolManager.sol
Normal file
@@ -0,0 +1,24 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
interface IYTPoolManager {
|
||||
function addLiquidityForAccount(
|
||||
address _fundingAccount,
|
||||
address _account,
|
||||
address _token,
|
||||
uint256 _amount,
|
||||
uint256 _minUsdy,
|
||||
uint256 _minYtLP
|
||||
) external returns (uint256);
|
||||
|
||||
function removeLiquidityForAccount(
|
||||
address _account,
|
||||
address _tokenOut,
|
||||
uint256 _ytLPAmount,
|
||||
uint256 _minOut,
|
||||
address _receiver
|
||||
) external returns (uint256);
|
||||
|
||||
function getPrice(bool _maximise) external view returns (uint256);
|
||||
}
|
||||
|
||||
7
contracts/interfaces/IYTPriceFeed.sol
Normal file
7
contracts/interfaces/IYTPriceFeed.sol
Normal file
@@ -0,0 +1,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
interface IYTPriceFeed {
|
||||
function getPrice(address _token, bool _maximise) external view returns (uint256);
|
||||
}
|
||||
|
||||
7
contracts/interfaces/IYTToken.sol
Normal file
7
contracts/interfaces/IYTToken.sol
Normal file
@@ -0,0 +1,7 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
interface IYTToken {
|
||||
function ytPrice() external view returns (uint256);
|
||||
function wusdPrice() external view returns (uint256);
|
||||
}
|
||||
15
contracts/interfaces/IYTVault.sol
Normal file
15
contracts/interfaces/IYTVault.sol
Normal file
@@ -0,0 +1,15 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
interface IYTVault {
|
||||
function buyUSDY(address _token, address _receiver) external returns (uint256);
|
||||
function sellUSDY(address _token, address _receiver) external returns (uint256);
|
||||
function swap(address _tokenIn, address _tokenOut, address _receiver) external returns (uint256);
|
||||
function getPoolValue(bool _maximise) external view returns (uint256);
|
||||
function getPrice(address _token, bool _maximise) external view returns (uint256);
|
||||
function getMaxPrice(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 getRedemptionFeeBasisPoints(address _token, uint256 _usdyAmount) external view returns (uint256);
|
||||
}
|
||||
|
||||
443
contracts/vault/YTAssetFactory.sol
Normal file
443
contracts/vault/YTAssetFactory.sol
Normal file
@@ -0,0 +1,443 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
||||
import "@openzeppelin/contracts/proxy/ERC1967/ERC1967Proxy.sol";
|
||||
import "./YTAssetVault.sol";
|
||||
|
||||
/**
|
||||
* @title YTAssetFactory
|
||||
* @notice 用于批量创建和管理YT资产金库合约的工厂
|
||||
* @dev UUPS可升级合约
|
||||
*/
|
||||
contract YTAssetFactory is Initializable, UUPSUpgradeable, OwnableUpgradeable {
|
||||
|
||||
error InvalidAddress();
|
||||
error VaultNotExists();
|
||||
error InvalidHardCap();
|
||||
|
||||
/// @notice YTAssetVault实现合约地址
|
||||
address public vaultImplementation;
|
||||
|
||||
/// @notice 所有创建的vault地址列表
|
||||
address[] public allVaults;
|
||||
|
||||
/// @notice vault地址 => 是否存在
|
||||
mapping(address => bool) public isVault;
|
||||
|
||||
/// @notice 默认硬顶值(0表示无限制)
|
||||
uint256 public defaultHardCap;
|
||||
|
||||
event VaultCreated(
|
||||
address indexed vault,
|
||||
address indexed manager,
|
||||
string name,
|
||||
string symbol,
|
||||
uint256 hardCap,
|
||||
uint256 index
|
||||
);
|
||||
event VaultImplementationUpdated(address indexed newImplementation);
|
||||
event DefaultHardCapSet(uint256 newDefaultHardCap);
|
||||
event HardCapSet(address indexed vault, uint256 newHardCap);
|
||||
event PricesUpdated(address indexed vault, uint256 wusdPrice, uint256 ytPrice);
|
||||
event NextRedemptionTimeSet(address indexed vault, uint256 redemptionTime);
|
||||
|
||||
/**
|
||||
* @notice 初始化工厂
|
||||
* @param _vaultImplementation YTAssetVault实现合约地址
|
||||
* @param _defaultHardCap 默认硬顶值
|
||||
*/
|
||||
function initialize(
|
||||
address _vaultImplementation,
|
||||
uint256 _defaultHardCap
|
||||
) external initializer {
|
||||
if (_vaultImplementation == address(0)) revert InvalidAddress();
|
||||
|
||||
__Ownable_init(msg.sender);
|
||||
__UUPSUpgradeable_init();
|
||||
|
||||
vaultImplementation = _vaultImplementation;
|
||||
defaultHardCap = _defaultHardCap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅owner可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
||||
|
||||
/**
|
||||
* @notice 更新YTAssetVault实现合约
|
||||
* @param _newImplementation 新的实现合约地址
|
||||
*/
|
||||
function setVaultImplementation(address _newImplementation) external onlyOwner {
|
||||
if (_newImplementation == address(0)) revert InvalidAddress();
|
||||
vaultImplementation = _newImplementation;
|
||||
emit VaultImplementationUpdated(_newImplementation);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置默认硬顶
|
||||
* @param _defaultHardCap 新的默认硬顶值
|
||||
*/
|
||||
function setDefaultHardCap(uint256 _defaultHardCap) external onlyOwner {
|
||||
defaultHardCap = _defaultHardCap;
|
||||
emit DefaultHardCapSet(_defaultHardCap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 创建新的YTAssetVault
|
||||
* @param _name YT代币名称
|
||||
* @param _symbol YT代币符号
|
||||
* @param _manager 管理员地址
|
||||
* @param _hardCap 硬顶限制(0表示使用默认值)
|
||||
* @param _wusd WUSD代币地址(传0使用默认地址)
|
||||
* @param _redemptionTime 赎回时间(Unix时间戳)
|
||||
* @param _initialWusdPrice 初始WUSD价格(精度1e30,传0则使用默认值1.0)
|
||||
* @param _initialYtPrice 初始YT价格(精度1e30,传0则使用默认值1.0)
|
||||
* @return vault 新创建的vault地址
|
||||
*/
|
||||
function createVault(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _manager,
|
||||
uint256 _hardCap,
|
||||
address _wusd,
|
||||
uint256 _redemptionTime,
|
||||
uint256 _initialWusdPrice,
|
||||
uint256 _initialYtPrice
|
||||
) external onlyOwner returns (address vault) {
|
||||
if (_manager == address(0)) revert InvalidAddress();
|
||||
|
||||
// 如果传入0,使用默认硬顶
|
||||
uint256 actualHardCap = _hardCap == 0 ? defaultHardCap : _hardCap;
|
||||
|
||||
// 编码初始化数据
|
||||
bytes memory initData = abi.encodeWithSelector(
|
||||
YTAssetVault.initialize.selector,
|
||||
_name,
|
||||
_symbol,
|
||||
_manager,
|
||||
actualHardCap,
|
||||
_wusd,
|
||||
_redemptionTime,
|
||||
_initialWusdPrice,
|
||||
_initialYtPrice
|
||||
);
|
||||
|
||||
// 部署代理合约
|
||||
vault = address(new ERC1967Proxy(vaultImplementation, initData));
|
||||
|
||||
// 记录vault信息
|
||||
allVaults.push(vault);
|
||||
isVault[vault] = true;
|
||||
|
||||
emit VaultCreated(
|
||||
vault,
|
||||
_manager,
|
||||
_name,
|
||||
_symbol,
|
||||
actualHardCap,
|
||||
allVaults.length - 1
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量创建vault
|
||||
* @param _names YT代币名称数组
|
||||
* @param _symbols YT代币符号数组
|
||||
* @param _managers 管理员地址数组
|
||||
* @param _hardCaps 硬顶数组
|
||||
* @param _wusd WUSD代币地址(传0使用默认地址)
|
||||
* @param _redemptionTimes 赎回时间数组(Unix时间戳)
|
||||
* @param _initialWusdPrices 初始WUSD价格数组(精度1e30)
|
||||
* @param _initialYtPrices 初始YT价格数组(精度1e30)
|
||||
* @return vaults 创建的vault地址数组
|
||||
*/
|
||||
function createVaultBatch(
|
||||
string[] memory _names,
|
||||
string[] memory _symbols,
|
||||
address[] memory _managers,
|
||||
uint256[] memory _hardCaps,
|
||||
address _wusd,
|
||||
uint256[] memory _redemptionTimes,
|
||||
uint256[] memory _initialWusdPrices,
|
||||
uint256[] memory _initialYtPrices
|
||||
) external returns (address[] memory vaults) {
|
||||
require(
|
||||
_names.length == _symbols.length &&
|
||||
_names.length == _managers.length &&
|
||||
_names.length == _hardCaps.length &&
|
||||
_names.length == _redemptionTimes.length &&
|
||||
_names.length == _initialWusdPrices.length &&
|
||||
_names.length == _initialYtPrices.length,
|
||||
"Length mismatch"
|
||||
);
|
||||
|
||||
vaults = new address[](_names.length);
|
||||
|
||||
for (uint256 i = 0; i < _names.length; i++) {
|
||||
vaults[i] = this.createVault(
|
||||
_names[i],
|
||||
_symbols[i],
|
||||
_managers[i],
|
||||
_hardCaps[i],
|
||||
_wusd,
|
||||
_redemptionTimes[i],
|
||||
_initialWusdPrices[i],
|
||||
_initialYtPrices[i]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置指定vault的硬顶
|
||||
* @param _vault vault地址
|
||||
* @param _hardCap 新的硬顶值
|
||||
*/
|
||||
function setHardCap(address _vault, uint256 _hardCap) external onlyOwner {
|
||||
if (!isVault[_vault]) revert VaultNotExists();
|
||||
|
||||
YTAssetVault(_vault).setHardCap(_hardCap);
|
||||
emit HardCapSet(_vault, _hardCap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量设置硬顶
|
||||
* @param _vaults vault地址数组
|
||||
* @param _hardCaps 硬顶值数组
|
||||
*/
|
||||
function setHardCapBatch(
|
||||
address[] memory _vaults,
|
||||
uint256[] memory _hardCaps
|
||||
) external onlyOwner {
|
||||
require(_vaults.length == _hardCaps.length, "Length mismatch");
|
||||
|
||||
for (uint256 i = 0; i < _vaults.length; i++) {
|
||||
if (!isVault[_vaults[i]]) revert VaultNotExists();
|
||||
YTAssetVault(_vaults[i]).setHardCap(_hardCaps[i]);
|
||||
emit HardCapSet(_vaults[i], _hardCaps[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置vault的管理员
|
||||
* @param _vault vault地址
|
||||
* @param _manager 新管理员地址
|
||||
*/
|
||||
function setVaultManager(address _vault, address _manager) external onlyOwner {
|
||||
if (!isVault[_vault]) revert VaultNotExists();
|
||||
if (_manager == address(0)) revert InvalidAddress();
|
||||
|
||||
YTAssetVault(_vault).setManager(_manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置vault的下一个赎回时间
|
||||
* @param _vault vault地址
|
||||
* @param _nextRedemptionTime 赎回时间(Unix时间戳)
|
||||
*/
|
||||
function setVaultNextRedemptionTime(address _vault, uint256 _nextRedemptionTime) external onlyOwner {
|
||||
if (!isVault[_vault]) revert VaultNotExists();
|
||||
|
||||
YTAssetVault(_vault).setNextRedemptionTime(_nextRedemptionTime);
|
||||
emit NextRedemptionTimeSet(_vault, _nextRedemptionTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量设置赎回时间
|
||||
* @param _vaults vault地址数组
|
||||
* @param _nextRedemptionTime 统一的赎回时间
|
||||
*/
|
||||
function setVaultNextRedemptionTimeBatch(
|
||||
address[] memory _vaults,
|
||||
uint256 _nextRedemptionTime
|
||||
) external onlyOwner {
|
||||
for (uint256 i = 0; i < _vaults.length; i++) {
|
||||
if (!isVault[_vaults[i]]) revert VaultNotExists();
|
||||
YTAssetVault(_vaults[i]).setNextRedemptionTime(_nextRedemptionTime);
|
||||
emit NextRedemptionTimeSet(_vaults[i], _nextRedemptionTime);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 暂停vault(紧急情况)
|
||||
* @param _vault vault地址
|
||||
*/
|
||||
function pauseVault(address _vault) external onlyOwner {
|
||||
if (!isVault[_vault]) revert VaultNotExists();
|
||||
|
||||
YTAssetVault(_vault).pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 恢复vault
|
||||
* @param _vault vault地址
|
||||
*/
|
||||
function unpauseVault(address _vault) external onlyOwner {
|
||||
if (!isVault[_vault]) revert VaultNotExists();
|
||||
|
||||
YTAssetVault(_vault).unpause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量暂停vaults
|
||||
* @param _vaults vault地址数组
|
||||
*/
|
||||
function pauseVaultBatch(address[] memory _vaults) external onlyOwner {
|
||||
for (uint256 i = 0; i < _vaults.length; i++) {
|
||||
if (!isVault[_vaults[i]]) revert VaultNotExists();
|
||||
YTAssetVault(_vaults[i]).pause();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量恢复vaults
|
||||
* @param _vaults vault地址数组
|
||||
*/
|
||||
function unpauseVaultBatch(address[] memory _vaults) external onlyOwner {
|
||||
for (uint256 i = 0; i < _vaults.length; i++) {
|
||||
if (!isVault[_vaults[i]]) revert VaultNotExists();
|
||||
YTAssetVault(_vaults[i]).unpause();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 更新vault价格
|
||||
* @param _vault vault地址
|
||||
* @param _wusdPrice WUSD价格(精度1e30)
|
||||
* @param _ytPrice YT价格(精度1e30)
|
||||
*/
|
||||
function updateVaultPrices(
|
||||
address _vault,
|
||||
uint256 _wusdPrice,
|
||||
uint256 _ytPrice
|
||||
) external onlyOwner {
|
||||
if (!isVault[_vault]) revert VaultNotExists();
|
||||
|
||||
YTAssetVault(_vault).updatePrices(_wusdPrice, _ytPrice);
|
||||
emit PricesUpdated(_vault, _wusdPrice, _ytPrice);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量更新价格
|
||||
* @param _vaults vault地址数组
|
||||
* @param _wusdPrices WUSD价格数组(精度1e30)
|
||||
* @param _ytPrices YT价格数组(精度1e30)
|
||||
*/
|
||||
function updateVaultPricesBatch(
|
||||
address[] memory _vaults,
|
||||
uint256[] memory _wusdPrices,
|
||||
uint256[] memory _ytPrices
|
||||
) external onlyOwner {
|
||||
require(
|
||||
_vaults.length == _wusdPrices.length &&
|
||||
_vaults.length == _ytPrices.length,
|
||||
"Length mismatch"
|
||||
);
|
||||
|
||||
for (uint256 i = 0; i < _vaults.length; i++) {
|
||||
if (!isVault[_vaults[i]]) revert VaultNotExists();
|
||||
YTAssetVault(_vaults[i]).updatePrices(_wusdPrices[i], _ytPrices[i]);
|
||||
emit PricesUpdated(_vaults[i], _wusdPrices[i], _ytPrices[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 升级指定vault
|
||||
* @param _vault vault地址
|
||||
* @param _newImplementation 新实现地址
|
||||
*/
|
||||
function upgradeVault(address _vault, address _newImplementation) external onlyOwner {
|
||||
if (!isVault[_vault]) revert VaultNotExists();
|
||||
if (_newImplementation == address(0)) revert InvalidAddress();
|
||||
|
||||
YTAssetVault(_vault).upgradeToAndCall(_newImplementation, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量升级vault
|
||||
* @param _vaults vault地址数组
|
||||
* @param _newImplementation 新实现地址
|
||||
*/
|
||||
function upgradeVaultBatch(
|
||||
address[] memory _vaults,
|
||||
address _newImplementation
|
||||
) external onlyOwner {
|
||||
if (_newImplementation == address(0)) revert InvalidAddress();
|
||||
|
||||
for (uint256 i = 0; i < _vaults.length; i++) {
|
||||
if (!isVault[_vaults[i]]) revert VaultNotExists();
|
||||
YTAssetVault(_vaults[i]).upgradeToAndCall(_newImplementation, "");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取所有vault数量
|
||||
*/
|
||||
function getVaultCount() external view returns (uint256) {
|
||||
return allVaults.length;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取指定范围的vault地址
|
||||
* @param _start 起始索引
|
||||
* @param _end 结束索引(不包含)
|
||||
*/
|
||||
function getVaults(uint256 _start, uint256 _end)
|
||||
external
|
||||
view
|
||||
returns (address[] memory vaults)
|
||||
{
|
||||
require(_start < _end && _end <= allVaults.length, "Invalid range");
|
||||
|
||||
vaults = new address[](_end - _start);
|
||||
for (uint256 i = _start; i < _end; i++) {
|
||||
vaults[i - _start] = allVaults[i];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取所有vault地址
|
||||
*/
|
||||
function getAllVaults() external view returns (address[] memory) {
|
||||
return allVaults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取vault详细信息
|
||||
* @param _vault vault地址
|
||||
*/
|
||||
function getVaultInfo(address _vault) external view returns (
|
||||
bool exists,
|
||||
uint256 totalAssets,
|
||||
uint256 idleAssets,
|
||||
uint256 managedAssets,
|
||||
uint256 totalSupply,
|
||||
uint256 hardCap,
|
||||
uint256 wusdPrice,
|
||||
uint256 ytPrice,
|
||||
uint256 nextRedemptionTime
|
||||
) {
|
||||
exists = isVault[_vault];
|
||||
if (!exists) return (false, 0, 0, 0, 0, 0, 0, 0, 0);
|
||||
(
|
||||
totalAssets,
|
||||
idleAssets,
|
||||
managedAssets,
|
||||
totalSupply,
|
||||
hardCap,
|
||||
wusdPrice,
|
||||
ytPrice,
|
||||
nextRedemptionTime
|
||||
) = YTAssetVault(_vault).getVaultInfo();
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
375
contracts/vault/YTAssetVault.sol
Normal file
375
contracts/vault/YTAssetVault.sol
Normal file
@@ -0,0 +1,375 @@
|
||||
// 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/utils/ReentrancyGuardUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
|
||||
/**
|
||||
* @title YTAssetVault
|
||||
* @notice 基于价格的资产金库,用户根据WUSD和YT代币价格进行兑换
|
||||
* @dev UUPS可升级合约,YT是份额代币
|
||||
*/
|
||||
contract YTAssetVault is
|
||||
Initializable,
|
||||
ERC20Upgradeable,
|
||||
UUPSUpgradeable,
|
||||
ReentrancyGuardUpgradeable,
|
||||
PausableUpgradeable
|
||||
{
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
error Forbidden();
|
||||
error HardCapExceeded();
|
||||
error InvalidAmount();
|
||||
error InvalidHardCap();
|
||||
error InvalidPrice();
|
||||
error InsufficientWUSD();
|
||||
error InsufficientYTA();
|
||||
error StillInLockPeriod();
|
||||
|
||||
/// @notice 工厂合约地址
|
||||
address public factory;
|
||||
|
||||
/// @notice 管理员地址
|
||||
address public manager;
|
||||
|
||||
/// @notice YT代币硬顶(最大可铸造的YT数量)
|
||||
uint256 public hardCap;
|
||||
|
||||
/// @notice 已提取用于管理的WUSD数量
|
||||
uint256 public managedAssets;
|
||||
|
||||
/// @notice WUSD代币地址
|
||||
address public wusdAddress;
|
||||
|
||||
/// @notice WUSD价格(精度1e30)
|
||||
uint256 public wusdPrice;
|
||||
|
||||
/// @notice YT价格(精度1e30)
|
||||
uint256 public ytPrice;
|
||||
|
||||
/// @notice 价格精度
|
||||
uint256 public constant PRICE_PRECISION = 1e30;
|
||||
|
||||
/// @notice 下一个赎回开放时间(所有用户统一)
|
||||
uint256 public nextRedemptionTime;
|
||||
|
||||
event HardCapSet(uint256 newHardCap);
|
||||
event ManagerSet(address indexed newManager);
|
||||
event AssetsWithdrawn(address indexed to, uint256 amount);
|
||||
event AssetsDeposited(uint256 amount);
|
||||
event PriceUpdated(uint256 wusdPrice, uint256 ytPrice, uint256 timestamp);
|
||||
event Buy(address indexed user, uint256 wusdAmount, uint256 ytAmount);
|
||||
event Sell(address indexed user, uint256 ytAmount, uint256 wusdAmount);
|
||||
event NextRedemptionTimeSet(uint256 newRedemptionTime);
|
||||
|
||||
modifier onlyFactory() {
|
||||
if (msg.sender != factory) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyManager() {
|
||||
if (msg.sender != manager) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 初始化金库
|
||||
* @param _name YT代币名称
|
||||
* @param _symbol YT代币符号
|
||||
* @param _manager 管理员地址
|
||||
* @param _hardCap 硬顶限制
|
||||
* @param _wusd WUSD代币地址(可选,传0则使用默认地址)
|
||||
* @param _redemptionTime 赎回时间(Unix时间戳)
|
||||
* @param _initialWusdPrice 初始WUSD价格(精度1e30,传0则使用默认值1.0)
|
||||
* @param _initialYtPrice 初始YT价格(精度1e30,传0则使用默认值1.0)
|
||||
*
|
||||
* @dev 价格精度为1e30
|
||||
*/
|
||||
function initialize(
|
||||
string memory _name,
|
||||
string memory _symbol,
|
||||
address _manager,
|
||||
uint256 _hardCap,
|
||||
address _wusd,
|
||||
uint256 _redemptionTime,
|
||||
uint256 _initialWusdPrice,
|
||||
uint256 _initialYtPrice
|
||||
) external initializer {
|
||||
wusdAddress = _wusd == address(0)
|
||||
? 0x7Cd017ca5ddb86861FA983a34b5F495C6F898c41
|
||||
: _wusd;
|
||||
|
||||
__ERC20_init(_name, _symbol);
|
||||
__UUPSUpgradeable_init();
|
||||
__ReentrancyGuard_init();
|
||||
__Pausable_init();
|
||||
|
||||
factory = msg.sender;
|
||||
manager = _manager;
|
||||
hardCap = _hardCap;
|
||||
|
||||
// 使用传入的初始价格,如果为0则使用默认值1.0
|
||||
wusdPrice = _initialWusdPrice == 0 ? PRICE_PRECISION : _initialWusdPrice;
|
||||
ytPrice = _initialYtPrice == 0 ? PRICE_PRECISION : _initialYtPrice;
|
||||
|
||||
// 设置赎回时间
|
||||
nextRedemptionTime = _redemptionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅factory可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyFactory {}
|
||||
|
||||
/**
|
||||
* @notice 设置硬顶
|
||||
* @param _hardCap 新的硬顶值
|
||||
*/
|
||||
function setHardCap(uint256 _hardCap) external onlyFactory {
|
||||
if (_hardCap < totalSupply()) revert InvalidHardCap();
|
||||
hardCap = _hardCap;
|
||||
emit HardCapSet(_hardCap);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置管理员
|
||||
* @param _manager 新管理员地址
|
||||
*/
|
||||
function setManager(address _manager) external onlyFactory {
|
||||
manager = _manager;
|
||||
emit ManagerSet(_manager);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 暂停合约(仅factory可调用)
|
||||
* @dev 暂停后,所有资金流动操作将被禁止
|
||||
*/
|
||||
function pause() external onlyFactory {
|
||||
_pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 恢复合约(仅factory可调用)
|
||||
*/
|
||||
function unpause() external onlyFactory {
|
||||
_unpause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置下一个赎回开放时间(仅factory可调用)
|
||||
* @param _nextRedemptionTime 下一个赎回时间(Unix时间戳)
|
||||
* @dev 所有用户统一在此时间后才能赎回,类似基金的赎回日
|
||||
*/
|
||||
function setNextRedemptionTime(uint256 _nextRedemptionTime) external onlyFactory {
|
||||
nextRedemptionTime = _nextRedemptionTime;
|
||||
emit NextRedemptionTimeSet(_nextRedemptionTime);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 更新价格(仅manager可调用)
|
||||
* @param _wusdPrice WUSD价格(精度1e30)
|
||||
* @param _ytPrice YT价格(精度1e30)
|
||||
*/
|
||||
function updatePrices(uint256 _wusdPrice, uint256 _ytPrice) external onlyFactory {
|
||||
if (_wusdPrice == 0 || _ytPrice == 0) revert InvalidPrice();
|
||||
|
||||
wusdPrice = _wusdPrice;
|
||||
ytPrice = _ytPrice;
|
||||
|
||||
emit PriceUpdated(_wusdPrice, _ytPrice, block.timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 用WUSD购买YT
|
||||
* @param _wusdAmount 支付的WUSD数量
|
||||
* @return ytAmount 实际获得的YT数量
|
||||
* @dev 首次购买时,YT价格 = WUSD价格(1:1兑换)
|
||||
*/
|
||||
function depositYT(uint256 _wusdAmount)
|
||||
external
|
||||
nonReentrant
|
||||
whenNotPaused
|
||||
returns (uint256 ytAmount)
|
||||
{
|
||||
if (_wusdAmount == 0) revert InvalidAmount();
|
||||
|
||||
// 计算可以购买的YT数量
|
||||
ytAmount = (_wusdAmount * wusdPrice) / ytPrice;
|
||||
|
||||
// 检查硬顶
|
||||
if (hardCap > 0 && totalSupply() + ytAmount > hardCap) {
|
||||
revert HardCapExceeded();
|
||||
}
|
||||
|
||||
// 转入WUSD
|
||||
IERC20(wusdAddress).safeTransferFrom(msg.sender, address(this), _wusdAmount);
|
||||
|
||||
// 铸造YT
|
||||
_mint(msg.sender, ytAmount);
|
||||
|
||||
emit Buy(msg.sender, _wusdAmount, ytAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 卖出YT换取WUSD(需要等到统一赎回时间)
|
||||
* @param _ytAmount 卖出的YT数量
|
||||
* @return wusdAmount 实际获得的WUSD数量
|
||||
*/
|
||||
function withdrawYT(uint256 _ytAmount)
|
||||
external
|
||||
nonReentrant
|
||||
whenNotPaused
|
||||
returns (uint256 wusdAmount)
|
||||
{
|
||||
if (_ytAmount == 0) revert InvalidAmount();
|
||||
if (balanceOf(msg.sender) < _ytAmount) revert InsufficientYTA();
|
||||
|
||||
// 检查是否到达统一赎回时间
|
||||
if (block.timestamp < nextRedemptionTime) {
|
||||
revert StillInLockPeriod();
|
||||
}
|
||||
|
||||
// 计算可以换取的WUSD数量
|
||||
wusdAmount = (_ytAmount * ytPrice) / wusdPrice;
|
||||
|
||||
// 检查合约是否有足够的WUSD
|
||||
uint256 availableWUSD = IERC20(wusdAddress).balanceOf(address(this));
|
||||
if (wusdAmount > availableWUSD) revert InsufficientWUSD();
|
||||
|
||||
// 销毁YT
|
||||
_burn(msg.sender, _ytAmount);
|
||||
|
||||
// 转出WUSD
|
||||
IERC20(wusdAddress).safeTransfer(msg.sender, wusdAmount);
|
||||
|
||||
emit Sell(msg.sender, _ytAmount, wusdAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 查询距离下次赎回开放还需等待多久
|
||||
* @return remainingTime 剩余时间(秒),0表示可以赎回
|
||||
*/
|
||||
function getTimeUntilNextRedemption() external view returns (uint256 remainingTime) {
|
||||
if (block.timestamp >= nextRedemptionTime) {
|
||||
return 0;
|
||||
}
|
||||
return nextRedemptionTime - block.timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 检查当前是否可以赎回
|
||||
* @return 是否可以赎回
|
||||
*/
|
||||
function canRedeemNow() external view returns (bool) {
|
||||
return block.timestamp >= nextRedemptionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 提取WUSD用于外部投资
|
||||
* @param _to 接收地址
|
||||
* @param _amount 提取数量
|
||||
*/
|
||||
function withdrawForManagement(address _to, uint256 _amount) external onlyManager nonReentrant whenNotPaused {
|
||||
if (_amount == 0) revert InvalidAmount();
|
||||
|
||||
uint256 availableAssets = IERC20(wusdAddress).balanceOf(address(this));
|
||||
if (_amount > availableAssets) revert InvalidAmount();
|
||||
|
||||
managedAssets += _amount;
|
||||
IERC20(wusdAddress).safeTransfer(_to, _amount);
|
||||
|
||||
emit AssetsWithdrawn(_to, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 将管理的资产归还到金库(可以归还更多,产生收益)
|
||||
* @param _amount 归还数量
|
||||
*/
|
||||
function depositManagedAssets(uint256 _amount) external onlyManager nonReentrant whenNotPaused {
|
||||
if (_amount == 0) revert InvalidAmount();
|
||||
|
||||
// 先更新状态(遵循CEI模式)
|
||||
if (_amount >= managedAssets) {
|
||||
// 归还金额 >= 已管理资产,managedAssets归零,多余部分是收益
|
||||
managedAssets = 0;
|
||||
} else {
|
||||
// 归还金额 < 已管理资产,部分归还
|
||||
managedAssets -= _amount;
|
||||
}
|
||||
|
||||
// 从manager转入WUSD到合约
|
||||
IERC20(wusdAddress).safeTransferFrom(msg.sender, address(this), _amount);
|
||||
|
||||
emit AssetsDeposited(_amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取总资产(包含被管理的资产)
|
||||
* @return 总资产 = 合约余额 + 被管理的资产
|
||||
*/
|
||||
function totalAssets() public view returns (uint256) {
|
||||
return IERC20(wusdAddress).balanceOf(address(this)) + managedAssets;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取空闲资产(可用于提取的资产)
|
||||
* @return 合约中实际持有的WUSD数量
|
||||
*/
|
||||
function idleAssets() public view returns (uint256) {
|
||||
return IERC20(wusdAddress).balanceOf(address(this));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 预览购买:计算支付指定WUSD可获得的YT数量
|
||||
* @param _wusdAmount 支付的WUSD数量
|
||||
* @return ytAmount 可获得的YT数量
|
||||
*/
|
||||
function previewBuy(uint256 _wusdAmount) external view returns (uint256 ytAmount) {
|
||||
ytAmount = (_wusdAmount * wusdPrice) / ytPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 预览卖出:计算卖出指定YT可获得的WUSD数量
|
||||
* @param _ytAmount 卖出的YT数量
|
||||
* @return wusdAmount 可获得的WUSD数量
|
||||
*/
|
||||
function previewSell(uint256 _ytAmount) external view returns (uint256 wusdAmount) {
|
||||
wusdAmount = (_ytAmount * ytPrice) / wusdPrice;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取金库信息
|
||||
*/
|
||||
function getVaultInfo() external view returns (
|
||||
uint256 _totalAssets,
|
||||
uint256 _idleAssets,
|
||||
uint256 _managedAssets,
|
||||
uint256 _totalSupply,
|
||||
uint256 _hardCap,
|
||||
uint256 _wusdPrice,
|
||||
uint256 _ytPrice,
|
||||
uint256 _nextRedemptionTime
|
||||
) {
|
||||
_totalAssets = totalAssets();
|
||||
_idleAssets = idleAssets();
|
||||
_managedAssets = managedAssets;
|
||||
_totalSupply = totalSupply();
|
||||
_hardCap = hardCap;
|
||||
_wusdPrice = wusdPrice;
|
||||
_ytPrice = ytPrice;
|
||||
_nextRedemptionTime = nextRedemptionTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
204
contracts/ytLending/Configurator.sol
Normal file
204
contracts/ytLending/Configurator.sol
Normal file
@@ -0,0 +1,204 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
||||
|
||||
import "./ConfiguratorStorage.sol";
|
||||
import "./LendingFactory.sol";
|
||||
|
||||
/**
|
||||
* @title Configurator
|
||||
* @notice 借贷池配置管理合约
|
||||
*/
|
||||
contract Configurator is
|
||||
ConfiguratorStorage,
|
||||
UUPSUpgradeable,
|
||||
OwnableUpgradeable
|
||||
{
|
||||
event SetFactory(address indexed lendingProxy, address indexed oldFactory, address indexed newFactory);
|
||||
event SetConfiguration(address indexed lendingProxy, Configuration oldConfiguration, Configuration newConfiguration);
|
||||
event AddAsset(address indexed lendingProxy, AssetConfig assetConfig);
|
||||
event UpdateAsset(address indexed lendingProxy, AssetConfig oldAssetConfig, AssetConfig newAssetConfig);
|
||||
event LendingDeployed(address indexed lendingProxy, address indexed newLending);
|
||||
|
||||
error AlreadyInitialized();
|
||||
error AssetDoesNotExist();
|
||||
error ConfigurationAlreadyExists();
|
||||
error InvalidAddress();
|
||||
|
||||
/// @custom:oz-upgrades-unsafe-allow constructor
|
||||
constructor() {
|
||||
_disableInitializers();
|
||||
}
|
||||
|
||||
function initialize() external initializer {
|
||||
__UUPSUpgradeable_init();
|
||||
__Ownable_init(msg.sender);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 授权升级函数 - 只有 owner 可以升级
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
||||
|
||||
/**
|
||||
* @notice 设置工厂合约地址
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @param newFactory 新工厂地址
|
||||
*/
|
||||
function setFactory(address lendingProxy, address newFactory) external onlyOwner {
|
||||
if (newFactory == address(0)) revert InvalidAddress();
|
||||
|
||||
address oldFactory = factory[lendingProxy];
|
||||
factory[lendingProxy] = newFactory;
|
||||
emit SetFactory(lendingProxy, oldFactory, newFactory);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置市场配置
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @param newConfiguration 新配置
|
||||
*/
|
||||
function setConfiguration(address lendingProxy, Configuration calldata newConfiguration)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
Configuration memory oldConfiguration = configuratorParams[lendingProxy];
|
||||
|
||||
// 防止修改不可变参数
|
||||
if (oldConfiguration.baseToken != address(0) &&
|
||||
(oldConfiguration.baseToken != newConfiguration.baseToken ||
|
||||
oldConfiguration.trackingIndexScale != newConfiguration.trackingIndexScale))
|
||||
revert ConfigurationAlreadyExists();
|
||||
|
||||
// 删除旧的资产配置
|
||||
delete configuratorParams[lendingProxy];
|
||||
|
||||
// 设置新配置
|
||||
configuratorParams[lendingProxy].baseToken = newConfiguration.baseToken;
|
||||
configuratorParams[lendingProxy].baseTokenPriceFeed = newConfiguration.baseTokenPriceFeed;
|
||||
configuratorParams[lendingProxy].supplyKink = newConfiguration.supplyKink;
|
||||
configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeLow = newConfiguration.supplyPerYearInterestRateSlopeLow;
|
||||
configuratorParams[lendingProxy].supplyPerYearInterestRateSlopeHigh = newConfiguration.supplyPerYearInterestRateSlopeHigh;
|
||||
configuratorParams[lendingProxy].supplyPerYearInterestRateBase = newConfiguration.supplyPerYearInterestRateBase;
|
||||
configuratorParams[lendingProxy].borrowKink = newConfiguration.borrowKink;
|
||||
configuratorParams[lendingProxy].borrowPerYearInterestRateSlopeLow = newConfiguration.borrowPerYearInterestRateSlopeLow;
|
||||
configuratorParams[lendingProxy].borrowPerYearInterestRateSlopeHigh = newConfiguration.borrowPerYearInterestRateSlopeHigh;
|
||||
configuratorParams[lendingProxy].borrowPerYearInterestRateBase = newConfiguration.borrowPerYearInterestRateBase;
|
||||
configuratorParams[lendingProxy].storeFrontPriceFactor = newConfiguration.storeFrontPriceFactor;
|
||||
configuratorParams[lendingProxy].trackingIndexScale = newConfiguration.trackingIndexScale;
|
||||
configuratorParams[lendingProxy].baseBorrowMin = newConfiguration.baseBorrowMin;
|
||||
configuratorParams[lendingProxy].targetReserves = newConfiguration.targetReserves;
|
||||
|
||||
// 复制资产配置
|
||||
for (uint i = 0; i < newConfiguration.assetConfigs.length; i++) {
|
||||
configuratorParams[lendingProxy].assetConfigs.push(newConfiguration.assetConfigs[i]);
|
||||
}
|
||||
|
||||
emit SetConfiguration(lendingProxy, oldConfiguration, newConfiguration);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 添加抵押资产
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @param assetConfig 资产配置
|
||||
*/
|
||||
function addAsset(address lendingProxy, AssetConfig calldata assetConfig)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
configuratorParams[lendingProxy].assetConfigs.push(assetConfig);
|
||||
emit AddAsset(lendingProxy, assetConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 更新资产配置
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @param newAssetConfig 新资产配置
|
||||
*/
|
||||
function updateAsset(address lendingProxy, AssetConfig calldata newAssetConfig)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
uint assetIndex = getAssetIndex(lendingProxy, newAssetConfig.asset);
|
||||
AssetConfig memory oldAssetConfig = configuratorParams[lendingProxy].assetConfigs[assetIndex];
|
||||
configuratorParams[lendingProxy].assetConfigs[assetIndex] = newAssetConfig;
|
||||
emit UpdateAsset(lendingProxy, oldAssetConfig, newAssetConfig);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 更新资产抵押率
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @param asset 资产地址
|
||||
* @param newBorrowCF 新借款抵押率
|
||||
*/
|
||||
function updateAssetBorrowCollateralFactor(
|
||||
address lendingProxy,
|
||||
address asset,
|
||||
uint64 newBorrowCF
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
uint assetIndex = getAssetIndex(lendingProxy, asset);
|
||||
configuratorParams[lendingProxy].assetConfigs[assetIndex].borrowCollateralFactor = newBorrowCF;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 更新资产供应上限
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @param asset 资产地址
|
||||
* @param newSupplyCap 新供应上限
|
||||
*/
|
||||
function updateAssetSupplyCap(
|
||||
address lendingProxy,
|
||||
address asset,
|
||||
uint128 newSupplyCap
|
||||
)
|
||||
external
|
||||
onlyOwner
|
||||
{
|
||||
uint assetIndex = getAssetIndex(lendingProxy, asset);
|
||||
configuratorParams[lendingProxy].assetConfigs[assetIndex].supplyCap = newSupplyCap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 部署新的 Lending 实现
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @return 新实现合约地址
|
||||
*/
|
||||
function deploy(address lendingProxy) external onlyOwner returns (address) {
|
||||
address newLending = LendingFactory(factory[lendingProxy]).deploy();
|
||||
emit LendingDeployed(lendingProxy, newLending);
|
||||
return newLending;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取资产索引
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @param asset 资产地址
|
||||
* @return 资产在配置数组中的索引
|
||||
*/
|
||||
function getAssetIndex(address lendingProxy, address asset) public view returns (uint) {
|
||||
AssetConfig[] memory assetConfigs = configuratorParams[lendingProxy].assetConfigs;
|
||||
uint numAssets = assetConfigs.length;
|
||||
for (uint i = 0; i < numAssets; ) {
|
||||
if (assetConfigs[i].asset == asset) {
|
||||
return i;
|
||||
}
|
||||
unchecked { i++; }
|
||||
}
|
||||
revert AssetDoesNotExist();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取市场配置
|
||||
* @param lendingProxy Lending 代理地址
|
||||
* @return 配置信息
|
||||
*/
|
||||
function getConfiguration(address lendingProxy) external view returns (Configuration memory) {
|
||||
return configuratorParams[lendingProxy];
|
||||
}
|
||||
}
|
||||
|
||||
17
contracts/ytLending/ConfiguratorStorage.sol
Normal file
17
contracts/ytLending/ConfiguratorStorage.sol
Normal file
@@ -0,0 +1,17 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./LendingConfiguration.sol";
|
||||
|
||||
/**
|
||||
* @title ConfiguratorStorage
|
||||
* @notice Configurator 存储定义
|
||||
*/
|
||||
abstract contract ConfiguratorStorage is LendingConfiguration {
|
||||
// Lending 代理地址 => 工厂合约地址
|
||||
mapping(address => address) public factory;
|
||||
|
||||
// Lending 代理地址 => 配置参数
|
||||
mapping(address => Configuration) public configuratorParams;
|
||||
}
|
||||
|
||||
663
contracts/ytLending/Lending.sol
Normal file
663
contracts/ytLending/Lending.sol
Normal file
@@ -0,0 +1,663 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.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 "./LendingStorage.sol";
|
||||
import "./LendingMath.sol";
|
||||
import "./interfaces/ILending.sol";
|
||||
import "./interfaces/IPriceFeed.sol";
|
||||
|
||||
/**
|
||||
* @title Lending
|
||||
* @notice 借贷池核心合约
|
||||
*/
|
||||
contract Lending is
|
||||
ILending,
|
||||
LendingStorage,
|
||||
UUPSUpgradeable,
|
||||
OwnableUpgradeable,
|
||||
PausableUpgradeable,
|
||||
ReentrancyGuardUpgradeable
|
||||
{
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
/// @custom:oz-upgrades-unsafe-allow constructor
|
||||
constructor() {
|
||||
_disableInitializers();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 初始化函数
|
||||
* @param config 市场配置
|
||||
*/
|
||||
function initialize(Configuration calldata config) external initializer {
|
||||
__UUPSUpgradeable_init();
|
||||
__Ownable_init(msg.sender);
|
||||
__Pausable_init();
|
||||
__ReentrancyGuard_init();
|
||||
|
||||
// 设置基础配置
|
||||
baseToken = config.baseToken;
|
||||
baseTokenPriceFeed = config.baseTokenPriceFeed;
|
||||
|
||||
// 常量:一年的秒数
|
||||
uint256 SECONDS_PER_YEAR = 365 * 24 * 60 * 60; // 31,536,000
|
||||
|
||||
// 设置利率参数(将年化利率转换为每秒利率,只计算一次)
|
||||
// 这样可以大幅降低每次计提利息的 Gas 成本并提高精度
|
||||
supplyKink = config.supplyKink;
|
||||
supplyPerSecondInterestRateSlopeLow = uint64(config.supplyPerYearInterestRateSlopeLow / SECONDS_PER_YEAR);
|
||||
supplyPerSecondInterestRateSlopeHigh = uint64(config.supplyPerYearInterestRateSlopeHigh / SECONDS_PER_YEAR);
|
||||
supplyPerSecondInterestRateBase = uint64(config.supplyPerYearInterestRateBase / SECONDS_PER_YEAR);
|
||||
|
||||
borrowKink = config.borrowKink;
|
||||
borrowPerSecondInterestRateSlopeLow = uint64(config.borrowPerYearInterestRateSlopeLow / SECONDS_PER_YEAR);
|
||||
borrowPerSecondInterestRateSlopeHigh = uint64(config.borrowPerYearInterestRateSlopeHigh / SECONDS_PER_YEAR);
|
||||
borrowPerSecondInterestRateBase = uint64(config.borrowPerYearInterestRateBase / SECONDS_PER_YEAR);
|
||||
|
||||
// 设置其他参数
|
||||
storeFrontPriceFactor = config.storeFrontPriceFactor;
|
||||
trackingIndexScale = config.trackingIndexScale;
|
||||
baseBorrowMin = config.baseBorrowMin;
|
||||
targetReserves = config.targetReserves;
|
||||
|
||||
// 初始化利息累计因子
|
||||
supplyIndex = 1e18;
|
||||
borrowIndex = 1e18;
|
||||
lastAccrualTime = block.timestamp;
|
||||
|
||||
// 设置抵押资产配置
|
||||
for (uint i = 0; i < config.assetConfigs.length; i++) {
|
||||
AssetConfig memory assetConfig = config.assetConfigs[i];
|
||||
|
||||
// 验证参数合法性(必须 < 1)
|
||||
require(assetConfig.liquidationFactor < 1e18, "Invalid liquidationFactor");
|
||||
require(assetConfig.borrowCollateralFactor < 1e18, "Invalid borrowCF");
|
||||
require(assetConfig.liquidateCollateralFactor < 1e18, "Invalid liquidateCF");
|
||||
|
||||
assetConfigs[assetConfig.asset] = assetConfig;
|
||||
assetList.push(assetConfig.asset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 授权升级函数 - 只有 owner 可以升级
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
||||
|
||||
/**
|
||||
* @notice 暂停合约
|
||||
*/
|
||||
function pause() external onlyOwner {
|
||||
_pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 恢复合约
|
||||
*/
|
||||
function unpause() external onlyOwner {
|
||||
_unpause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计提利息
|
||||
*/
|
||||
function accrueInterest() public {
|
||||
uint256 timeElapsed = block.timestamp - lastAccrualTime;
|
||||
if (timeElapsed == 0) return;
|
||||
|
||||
// 计算实际的 totalSupply 和 totalBorrow(含利息)
|
||||
// 注意:totalSupplyBase 和 totalBorrowBase 都是正数本金
|
||||
// supplyIndex 用于存款,borrowIndex 用于借款
|
||||
uint256 totalSupply = (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
uint256 totalBorrow = (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
|
||||
uint64 utilization = LendingMath.getUtilization(totalSupply, totalBorrow);
|
||||
|
||||
// 计算供应利率和借款利率(每秒利率)
|
||||
uint64 supplyRate = LendingMath.getSupplyRate(
|
||||
utilization,
|
||||
supplyKink,
|
||||
supplyPerSecondInterestRateSlopeLow,
|
||||
supplyPerSecondInterestRateSlopeHigh,
|
||||
supplyPerSecondInterestRateBase
|
||||
);
|
||||
|
||||
uint64 borrowRate = LendingMath.getBorrowRate(
|
||||
utilization,
|
||||
borrowKink,
|
||||
borrowPerSecondInterestRateSlopeLow,
|
||||
borrowPerSecondInterestRateSlopeHigh,
|
||||
borrowPerSecondInterestRateBase
|
||||
);
|
||||
|
||||
// 更新利息累计因子(使用每秒利率,计算更精确且 Gas 更低)
|
||||
supplyIndex = LendingMath.accrueInterest(supplyIndex, supplyRate, timeElapsed);
|
||||
borrowIndex = LendingMath.accrueInterest(borrowIndex, borrowRate, timeElapsed);
|
||||
|
||||
lastAccrualTime = block.timestamp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 存入基础资产
|
||||
*/
|
||||
function supply(uint256 amount) external override nonReentrant whenNotPaused {
|
||||
accrueInterest();
|
||||
|
||||
IERC20(baseToken).safeTransferFrom(msg.sender, address(this), amount);
|
||||
|
||||
// 获取用户当前本金
|
||||
UserBasic memory user = userBasic[msg.sender];
|
||||
int104 oldPrincipal = user.principal;
|
||||
|
||||
// 计算当前实际余额(含利息)
|
||||
uint256 index = oldPrincipal >= 0 ? supplyIndex : borrowIndex;
|
||||
int256 oldBalance = LendingMath.principalToBalance(oldPrincipal, index);
|
||||
|
||||
// 计算新余额(增加存款)
|
||||
int256 newBalance = oldBalance + int256(amount);
|
||||
|
||||
// 转换为新本金(可能从借款变为存款)
|
||||
uint256 newIndex = newBalance >= 0 ? supplyIndex : borrowIndex;
|
||||
int104 newPrincipal = LendingMath.balanceToPrincipal(newBalance, newIndex);
|
||||
|
||||
// 计算还款和存款金额
|
||||
(uint104 repayAmount, uint104 supplyAmount) = LendingMath.repayAndSupplyAmount(oldPrincipal, newPrincipal);
|
||||
|
||||
// 更新全局状态
|
||||
totalBorrowBase -= repayAmount;
|
||||
totalSupplyBase += supplyAmount;
|
||||
|
||||
// 更新用户本金
|
||||
userBasic[msg.sender].principal = newPrincipal;
|
||||
|
||||
emit Supply(msg.sender, msg.sender, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 取出基础资产(如果余额不足会自动借款)
|
||||
*/
|
||||
function withdraw(uint256 amount) external override nonReentrant whenNotPaused {
|
||||
accrueInterest();
|
||||
|
||||
// 获取用户当前本金
|
||||
UserBasic memory user = userBasic[msg.sender];
|
||||
int104 oldPrincipal = user.principal;
|
||||
|
||||
// 计算当前实际余额(含利息)
|
||||
uint256 index = oldPrincipal >= 0 ? supplyIndex : borrowIndex;
|
||||
int256 oldBalance = LendingMath.principalToBalance(oldPrincipal, index);
|
||||
|
||||
// 计算新余额
|
||||
int256 newBalance = oldBalance - int256(amount);
|
||||
|
||||
// 转换为新本金
|
||||
uint256 newIndex = newBalance >= 0 ? supplyIndex : borrowIndex;
|
||||
int104 newPrincipal = LendingMath.balanceToPrincipal(newBalance, newIndex);
|
||||
|
||||
// 计算提取和借款金额
|
||||
(uint104 withdrawAmount, uint104 borrowAmount) = LendingMath.withdrawAndBorrowAmount(oldPrincipal, newPrincipal);
|
||||
|
||||
// 更新全局状态
|
||||
totalSupplyBase -= withdrawAmount;
|
||||
totalBorrowBase += borrowAmount;
|
||||
|
||||
// 更新用户本金
|
||||
userBasic[msg.sender].principal = newPrincipal;
|
||||
|
||||
// 如果变成负余额(借款),检查抵押品
|
||||
if (newBalance < 0) {
|
||||
if (uint256(-newBalance) < baseBorrowMin) revert BorrowTooSmall();
|
||||
if (!_isSolvent(msg.sender)) revert InsufficientCollateral();
|
||||
}
|
||||
|
||||
IERC20(baseToken).safeTransfer(msg.sender, amount);
|
||||
|
||||
emit Withdraw(msg.sender, msg.sender, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 存入抵押品
|
||||
*/
|
||||
function supplyCollateral(address asset, uint256 amount) external override nonReentrant whenNotPaused {
|
||||
AssetConfig memory config = assetConfigs[asset];
|
||||
if (config.asset == address(0)) revert Unauthorized();
|
||||
|
||||
uint256 newTotal = userCollateral[msg.sender][asset] + amount;
|
||||
if (newTotal > config.supplyCap) revert SupplyCapExceeded();
|
||||
|
||||
IERC20(asset).safeTransferFrom(msg.sender, address(this), amount);
|
||||
|
||||
userCollateral[msg.sender][asset] += amount;
|
||||
|
||||
emit SupplyCollateral(msg.sender, msg.sender, asset, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 取出抵押品
|
||||
*/
|
||||
function withdrawCollateral(address asset, uint256 amount) external override nonReentrant whenNotPaused {
|
||||
accrueInterest();
|
||||
|
||||
if (userCollateral[msg.sender][asset] < amount) revert InsufficientBalance();
|
||||
|
||||
userCollateral[msg.sender][asset] -= amount;
|
||||
|
||||
// 检查是否仍有足够的抵押品(如果有债务)
|
||||
int104 principal = userBasic[msg.sender].principal;
|
||||
if (principal < 0) {
|
||||
if (!_isSolvent(msg.sender)) revert InsufficientCollateral();
|
||||
}
|
||||
|
||||
IERC20(asset).safeTransfer(msg.sender, amount);
|
||||
|
||||
emit WithdrawCollateral(msg.sender, msg.sender, asset, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 借款
|
||||
*/
|
||||
function borrow(uint256 amount) external override nonReentrant whenNotPaused {
|
||||
accrueInterest();
|
||||
|
||||
// 获取用户当前本金
|
||||
UserBasic memory user = userBasic[msg.sender];
|
||||
int104 oldPrincipal = user.principal;
|
||||
|
||||
// 计算当前实际余额(含利息)
|
||||
// 如果 principal >= 0(存款),使用 supplyIndex
|
||||
// 如果 principal < 0(借款),使用 borrowIndex
|
||||
uint256 index = oldPrincipal >= 0 ? supplyIndex : borrowIndex;
|
||||
int256 oldBalance = LendingMath.principalToBalance(oldPrincipal, index);
|
||||
|
||||
// 计算新余额(减去借款额)
|
||||
int256 newBalance = oldBalance - int256(amount);
|
||||
|
||||
// 检查最小借款额
|
||||
if (newBalance < 0 && uint256(-newBalance) < baseBorrowMin) revert BorrowTooSmall();
|
||||
|
||||
// 转换为新本金(新状态可能从存款变为借款)
|
||||
uint256 newIndex = newBalance >= 0 ? supplyIndex : borrowIndex;
|
||||
int104 newPrincipal = LendingMath.balanceToPrincipal(newBalance, newIndex);
|
||||
|
||||
// 计算提取和借款金额
|
||||
(uint104 withdrawAmount, uint104 borrowAmount) = LendingMath.withdrawAndBorrowAmount(oldPrincipal, newPrincipal);
|
||||
|
||||
// 更新全局状态
|
||||
totalSupplyBase -= withdrawAmount;
|
||||
totalBorrowBase += borrowAmount;
|
||||
|
||||
// 更新用户本金
|
||||
userBasic[msg.sender].principal = newPrincipal;
|
||||
|
||||
// 检查抵押品是否充足
|
||||
if (!_isSolvent(msg.sender)) revert InsufficientCollateral();
|
||||
|
||||
IERC20(baseToken).safeTransfer(msg.sender, amount);
|
||||
|
||||
emit Withdraw(msg.sender, msg.sender, amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 清算不良债务(内部实现)
|
||||
*/
|
||||
function _absorbInternal(address absorber, address borrower) internal {
|
||||
if (!isLiquidatable(borrower)) revert NotLiquidatable();
|
||||
|
||||
// 获取用户当前本金
|
||||
UserBasic memory user = userBasic[borrower];
|
||||
int104 oldPrincipal = user.principal;
|
||||
|
||||
// 计算当前实际余额(含利息累计的债务)
|
||||
int256 oldBalance = LendingMath.principalToBalance(oldPrincipal, borrowIndex);
|
||||
if (oldBalance >= 0) revert NotLiquidatable();
|
||||
|
||||
// 计算所有抵押品的总价值(按 liquidationFactor 折扣)
|
||||
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice();
|
||||
uint256 totalCollateralValue = 0;
|
||||
|
||||
for (uint i = 0; i < assetList.length; i++) {
|
||||
address asset = assetList[i];
|
||||
uint256 collateralAmount = userCollateral[borrower][asset];
|
||||
|
||||
if (collateralAmount > 0) {
|
||||
AssetConfig memory assetConfig = assetConfigs[asset];
|
||||
uint256 assetPrice = IPriceFeed(assetConfig.priceFeed).getPrice();
|
||||
|
||||
// 计算抵押品价值(USD,8位精度)
|
||||
uint256 assetScale = 10 ** assetConfig.decimals;
|
||||
uint256 collateralValueUSD = (collateralAmount * assetPrice) / assetScale;
|
||||
|
||||
// 应用 liquidationFactor 折扣
|
||||
uint256 discountedValue = (collateralValueUSD * assetConfig.liquidationFactor) / 1e18;
|
||||
totalCollateralValue += discountedValue;
|
||||
|
||||
// 将抵押品转移到清算库存
|
||||
userCollateral[borrower][asset] = 0;
|
||||
collateralReserves[asset] += collateralAmount;
|
||||
|
||||
// 发射抵押品吸收事件
|
||||
emit AbsorbCollateral(absorber, borrower, asset, collateralAmount, collateralValueUSD);
|
||||
}
|
||||
}
|
||||
|
||||
// 将抵押品价值转换为 baseToken 数量
|
||||
uint256 baseScale = 10 ** IERC20Metadata(baseToken).decimals();
|
||||
uint256 collateralInBase = (totalCollateralValue * baseScale) / basePrice;
|
||||
|
||||
// 计算新余额:oldBalance(负数)+ 抵押品价值
|
||||
int256 newBalance = oldBalance + int256(collateralInBase);
|
||||
|
||||
// 如果新余额仍为负,强制归零(坏账由协议承担)
|
||||
if (newBalance < 0) {
|
||||
newBalance = 0;
|
||||
}
|
||||
|
||||
// 转换为新本金
|
||||
int104 newPrincipal = LendingMath.balanceToPrincipal(newBalance, supplyIndex);
|
||||
|
||||
// 更新用户本金
|
||||
userBasic[borrower].principal = newPrincipal;
|
||||
|
||||
// 计算偿还和供应金额
|
||||
(uint104 repayAmount, uint104 supplyAmount) = LendingMath.repayAndSupplyAmount(oldPrincipal, newPrincipal);
|
||||
|
||||
// 更新全局状态
|
||||
// 储备金通过减少 totalBorrowBase 和增加 totalSupplyBase 来承担坏账
|
||||
totalSupplyBase += supplyAmount;
|
||||
totalBorrowBase -= repayAmount;
|
||||
|
||||
// 计算协议支付的债务(坏账部分)
|
||||
uint256 basePaidOut = uint256(newBalance - oldBalance);
|
||||
uint256 valueOfBasePaidOut = (basePaidOut * basePrice) / baseScale;
|
||||
|
||||
// 发射债务吸收事件
|
||||
emit AbsorbDebt(absorber, borrower, basePaidOut, valueOfBasePaidOut);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 清算不良债务(单个)
|
||||
*/
|
||||
function absorb(address borrower) external override nonReentrant whenNotPaused {
|
||||
accrueInterest();
|
||||
_absorbInternal(msg.sender, borrower);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量清算不良债务
|
||||
*/
|
||||
function absorbMultiple(address absorber, address[] calldata accounts) external override nonReentrant whenNotPaused {
|
||||
accrueInterest();
|
||||
for (uint i = 0; i < accounts.length; ) {
|
||||
_absorbInternal(absorber, accounts[i]);
|
||||
unchecked { i++; }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 购买清算后的抵押品
|
||||
*/
|
||||
function buyCollateral(
|
||||
address asset,
|
||||
uint256 minAmount,
|
||||
uint256 baseAmount,
|
||||
address recipient
|
||||
) external override nonReentrant whenNotPaused {
|
||||
if (collateralReserves[asset] == 0) revert InsufficientBalance();
|
||||
|
||||
// 计算可购买的抵押品数量
|
||||
uint256 collateralAmount = quoteCollateral(asset, baseAmount);
|
||||
|
||||
// 验证数量
|
||||
if (collateralAmount < minAmount) revert InsufficientBalance();
|
||||
if (collateralAmount > collateralReserves[asset]) revert InsufficientBalance();
|
||||
|
||||
// 检查储备金是否充足(如果已达到目标,不再出售抵押品)
|
||||
uint256 balance = IERC20(baseToken).balanceOf(address(this));
|
||||
uint256 totalSupply = (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
uint256 totalBorrow = (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
int256 currentReserves = int256(balance) - int256(totalSupply) + int256(totalBorrow);
|
||||
if (currentReserves >= 0 && uint256(currentReserves) >= targetReserves) {
|
||||
revert InsufficientBalance(); // 储备金充足,无需出售
|
||||
}
|
||||
|
||||
// 收取清算人支付的资金
|
||||
IERC20(baseToken).safeTransferFrom(msg.sender, address(this), baseAmount);
|
||||
|
||||
// 抵押品出库
|
||||
collateralReserves[asset] -= collateralAmount;
|
||||
|
||||
// 转账抵押品到指定接收人
|
||||
IERC20(asset).safeTransfer(recipient, collateralAmount);
|
||||
|
||||
// 注意:收入会自动体现在 getReserves() 中,因为 balance 增加了
|
||||
|
||||
emit BuyCollateral(msg.sender, asset, baseAmount, collateralAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算支付指定baseAmount可购买的抵押品数量
|
||||
*/
|
||||
function quoteCollateral(address asset, uint256 baseAmount) public view override returns (uint256) {
|
||||
AssetConfig memory assetConfig = assetConfigs[asset];
|
||||
|
||||
uint256 assetPrice = IPriceFeed(assetConfig.priceFeed).getPrice();
|
||||
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice();
|
||||
|
||||
// 计算折扣率 - 使用 Compound V3 的 mulFactor 方式
|
||||
// discountFactor = storeFrontPriceFactor * (FACTOR_SCALE - liquidationFactor) / FACTOR_SCALE
|
||||
uint256 FACTOR_SCALE = 1e18;
|
||||
uint256 discountFactor = (storeFrontPriceFactor * (FACTOR_SCALE - assetConfig.liquidationFactor)) / FACTOR_SCALE;
|
||||
|
||||
// 计算折扣后的资产价格
|
||||
// assetPriceDiscounted = assetPrice * (FACTOR_SCALE - discountFactor) / FACTOR_SCALE
|
||||
uint256 assetPriceDiscounted = (assetPrice * (FACTOR_SCALE - discountFactor)) / FACTOR_SCALE;
|
||||
|
||||
// 计算可购买的抵押品数量
|
||||
// 公式:(basePrice * baseAmount * assetScale) / (assetPriceDiscounted * baseScale)
|
||||
uint256 baseScale = 10 ** uint256(IERC20Metadata(baseToken).decimals());
|
||||
uint256 assetScale = 10 ** uint256(assetConfig.decimals);
|
||||
|
||||
// 使用中间变量分步计算,避免潜在的溢出
|
||||
// 先计算分子和分母,再进行除法
|
||||
return (basePrice * baseAmount * assetScale) / (assetPriceDiscounted * baseScale);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 检查账户偿付能力
|
||||
*/
|
||||
function _isSolvent(address account) internal view returns (bool) {
|
||||
int104 principal = userBasic[account].principal;
|
||||
if (principal >= 0) return true;
|
||||
|
||||
// 计算实际债务(含利息)- 使用 borrowIndex
|
||||
int256 balance = LendingMath.principalToBalance(principal, borrowIndex);
|
||||
uint256 debt = uint256(-balance);
|
||||
|
||||
// 将 debt 转换为美元价值(使用 baseToken 价格)
|
||||
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice();
|
||||
uint256 baseDecimals = IERC20Metadata(baseToken).decimals();
|
||||
uint256 debtValue = (debt * basePrice) / (10 ** baseDecimals);
|
||||
|
||||
// 计算借款能力(抵押品价值已经在 _getCollateralValue 中应用了借款系数)
|
||||
uint256 borrowCapacity = _getCollateralValue(account);
|
||||
|
||||
// 比较:借款能力 >= 债务价值
|
||||
return borrowCapacity >= debtValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算账户抵押品总价值
|
||||
*/
|
||||
function _getCollateralValue(address account) internal view returns (uint256) {
|
||||
uint256 totalValue = 0;
|
||||
|
||||
for (uint i = 0; i < assetList.length; i++) {
|
||||
address asset = assetList[i];
|
||||
uint256 amount = userCollateral[account][asset];
|
||||
if (amount > 0) {
|
||||
AssetConfig memory config = assetConfigs[asset];
|
||||
uint256 price = IPriceFeed(config.priceFeed).getPrice();
|
||||
uint256 value = LendingMath.getCollateralValue(amount, price, config.decimals);
|
||||
totalValue += (value * config.borrowCollateralFactor) / 1e18;
|
||||
}
|
||||
}
|
||||
|
||||
return totalValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取最小借款抵押率
|
||||
*/
|
||||
function _getMinBorrowCollateralFactor() internal view returns (uint64) {
|
||||
uint64 minFactor = type(uint64).max;
|
||||
for (uint i = 0; i < assetList.length; i++) {
|
||||
uint64 factor = assetConfigs[assetList[i]].borrowCollateralFactor;
|
||||
if (factor < minFactor) minFactor = factor;
|
||||
}
|
||||
return minFactor;
|
||||
}
|
||||
|
||||
// ========== View Functions ==========
|
||||
|
||||
function getBalance(address account) external view override returns (int256) {
|
||||
int104 principal = userBasic[account].principal;
|
||||
// 使用 supplyIndex 计算实际余额(含利息)
|
||||
return LendingMath.principalToBalance(principal, supplyIndex);
|
||||
}
|
||||
|
||||
function balanceOf(address account) external view override returns (uint256) {
|
||||
int104 principal = userBasic[account].principal;
|
||||
if (principal <= 0) return 0;
|
||||
// 只返回正余额(存款)
|
||||
return uint256(LendingMath.principalToBalance(principal, supplyIndex));
|
||||
}
|
||||
|
||||
function borrowBalanceOf(address account) external view override returns (uint256) {
|
||||
int104 principal = userBasic[account].principal;
|
||||
if (principal >= 0) return 0;
|
||||
// 只返回负余额(借款),转为正数
|
||||
int256 balance = LendingMath.principalToBalance(principal, borrowIndex);
|
||||
return uint256(-balance);
|
||||
}
|
||||
|
||||
function getCollateral(address account, address asset) external view override returns (uint256) {
|
||||
return userCollateral[account][asset];
|
||||
}
|
||||
|
||||
function isLiquidatable(address account) public view override returns (bool) {
|
||||
int104 principal = userBasic[account].principal;
|
||||
if (principal >= 0) return false;
|
||||
|
||||
// 计算实际债务(含利息)
|
||||
int256 balance = LendingMath.principalToBalance(principal, borrowIndex);
|
||||
uint256 debt = uint256(-balance);
|
||||
|
||||
// 将 debt 转换为美元价值(使用 baseToken 价格和 price feed 精度)
|
||||
uint256 basePrice = IPriceFeed(baseTokenPriceFeed).getPrice();
|
||||
uint256 baseDecimals = IERC20Metadata(baseToken).decimals();
|
||||
uint256 debtValue = (debt * basePrice) / (10 ** baseDecimals);
|
||||
|
||||
// 计算抵押品总价值(清算阈值)
|
||||
uint256 collateralValue = 0;
|
||||
for (uint i = 0; i < assetList.length; i++) {
|
||||
address asset = assetList[i];
|
||||
uint256 amount = userCollateral[account][asset];
|
||||
if (amount > 0) {
|
||||
AssetConfig memory config = assetConfigs[asset];
|
||||
uint256 price = IPriceFeed(config.priceFeed).getPrice();
|
||||
uint256 value = LendingMath.getCollateralValue(amount, price, config.decimals);
|
||||
collateralValue += (value * config.liquidateCollateralFactor) / 1e18;
|
||||
}
|
||||
}
|
||||
|
||||
// 比较:债务价值 > 抵押品清算阈值价值
|
||||
return debtValue > collateralValue;
|
||||
}
|
||||
|
||||
function getTotalSupply() external view returns (uint256) {
|
||||
return (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
}
|
||||
|
||||
function getTotalBorrow() external view returns (uint256) {
|
||||
return (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
}
|
||||
|
||||
function getCollateralReserves(address asset) external view override returns (uint256) {
|
||||
return collateralReserves[asset];
|
||||
}
|
||||
|
||||
function getReserves() external view override returns (int256) {
|
||||
// 计算实际总供应和总借款(含利息)
|
||||
uint256 balance = IERC20(baseToken).balanceOf(address(this));
|
||||
uint256 totalSupply = (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
uint256 totalBorrow = (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
|
||||
// reserves = balance - totalSupply + totalBorrow
|
||||
return int256(balance) - int256(totalSupply) + int256(totalBorrow);
|
||||
}
|
||||
|
||||
function getUtilization() external view override returns (uint256) {
|
||||
uint256 totalSupply = (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
uint256 totalBorrow = (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
return LendingMath.getUtilization(totalSupply, totalBorrow);
|
||||
}
|
||||
|
||||
function getSupplyRate() external view override returns (uint64) {
|
||||
uint256 totalSupply = (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
uint256 totalBorrow = (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
uint64 utilization = LendingMath.getUtilization(totalSupply, totalBorrow);
|
||||
uint64 perSecondRate = LendingMath.getSupplyRate(
|
||||
utilization,
|
||||
supplyKink,
|
||||
supplyPerSecondInterestRateSlopeLow,
|
||||
supplyPerSecondInterestRateSlopeHigh,
|
||||
supplyPerSecondInterestRateBase
|
||||
);
|
||||
// 转换为年化利率(APY)
|
||||
return perSecondRate * 31536000; // SECONDS_PER_YEAR
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 提取协议储备金(仅 owner)
|
||||
*/
|
||||
function withdrawReserves(address to, uint256 amount) external override onlyOwner nonReentrant {
|
||||
uint256 balance = IERC20(baseToken).balanceOf(address(this));
|
||||
uint256 totalSupply = (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
uint256 totalBorrow = (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
int256 currentReserves = int256(balance) - int256(totalSupply) + int256(totalBorrow);
|
||||
|
||||
// 检查储备金是否充足
|
||||
if (currentReserves < 0 || amount > uint256(currentReserves)) {
|
||||
revert InsufficientReserves();
|
||||
}
|
||||
|
||||
// 转账储备金
|
||||
IERC20(baseToken).safeTransfer(to, amount);
|
||||
|
||||
emit WithdrawReserves(to, amount);
|
||||
}
|
||||
|
||||
function getBorrowRate() external view override returns (uint64) {
|
||||
uint256 totalSupply = (uint256(totalSupplyBase) * supplyIndex) / 1e18;
|
||||
uint256 totalBorrow = (uint256(totalBorrowBase) * borrowIndex) / 1e18;
|
||||
uint64 utilization = LendingMath.getUtilization(totalSupply, totalBorrow);
|
||||
uint64 perSecondRate = LendingMath.getBorrowRate(
|
||||
utilization,
|
||||
borrowKink,
|
||||
borrowPerSecondInterestRateSlopeLow,
|
||||
borrowPerSecondInterestRateSlopeHigh,
|
||||
borrowPerSecondInterestRateBase
|
||||
);
|
||||
// 转换为年化利率(APY)
|
||||
return perSecondRate * 31536000; // SECONDS_PER_YEAR
|
||||
}
|
||||
}
|
||||
|
||||
43
contracts/ytLending/LendingConfiguration.sol
Normal file
43
contracts/ytLending/LendingConfiguration.sol
Normal file
@@ -0,0 +1,43 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @title LendingConfiguration
|
||||
* @notice 借贷池配置结构体定义
|
||||
*/
|
||||
contract LendingConfiguration {
|
||||
struct AssetConfig {
|
||||
address asset; // 资产地址
|
||||
address priceFeed; // 价格预言机地址
|
||||
uint8 decimals; // 小数位数
|
||||
uint64 borrowCollateralFactor; // 借款抵押率 (例: 0.8e18 = 80%)
|
||||
uint64 liquidateCollateralFactor; // 清算抵押率 (例: 0.85e18 = 85%)
|
||||
uint64 liquidationFactor; // 清算激励 (例: 1.05e18 = 5%折扣)
|
||||
uint128 supplyCap; // 供应上限
|
||||
}
|
||||
|
||||
struct Configuration {
|
||||
address baseToken; // 基础资产(借出的资产,如 USDC)
|
||||
address baseTokenPriceFeed; // 基础资产价格预言机
|
||||
|
||||
// 利率模型参数
|
||||
uint64 supplyKink; // 供应拐点利用率
|
||||
uint64 supplyPerYearInterestRateSlopeLow; // 供应拐点前斜率
|
||||
uint64 supplyPerYearInterestRateSlopeHigh; // 供应拐点后斜率
|
||||
uint64 supplyPerYearInterestRateBase; // 供应基础利率
|
||||
|
||||
uint64 borrowKink; // 借款拐点利用率
|
||||
uint64 borrowPerYearInterestRateSlopeLow; // 借款拐点前斜率
|
||||
uint64 borrowPerYearInterestRateSlopeHigh; // 借款拐点后斜率
|
||||
uint64 borrowPerYearInterestRateBase; // 借款基础利率
|
||||
|
||||
// 其他核心参数
|
||||
uint64 storeFrontPriceFactor; // 清算价格折扣
|
||||
uint64 trackingIndexScale; // 追踪索引比例
|
||||
uint104 baseBorrowMin; // 最小借款额
|
||||
uint104 targetReserves; // 目标储备金
|
||||
|
||||
AssetConfig[] assetConfigs; // 抵押资产配置数组
|
||||
}
|
||||
}
|
||||
|
||||
28
contracts/ytLending/LendingFactory.sol
Normal file
28
contracts/ytLending/LendingFactory.sol
Normal file
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||
import "./Lending.sol";
|
||||
import "./LendingConfiguration.sol";
|
||||
|
||||
/**
|
||||
* @title LendingFactory
|
||||
* @notice 工厂合约 - 用于部署新的 Lending 实现
|
||||
*/
|
||||
contract LendingFactory is LendingConfiguration, Ownable {
|
||||
|
||||
constructor() Ownable(msg.sender) {}
|
||||
|
||||
event LendingDeployed(address indexed lending);
|
||||
|
||||
/**
|
||||
* @notice 部署新的 Lending 实现合约
|
||||
* @return 新 Lending 合约地址
|
||||
*/
|
||||
function deploy() external onlyOwner returns (address) {
|
||||
Lending lending = new Lending();
|
||||
emit LendingDeployed(address(lending));
|
||||
return address(lending);
|
||||
}
|
||||
}
|
||||
|
||||
160
contracts/ytLending/LendingMath.sol
Normal file
160
contracts/ytLending/LendingMath.sol
Normal file
@@ -0,0 +1,160 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @title LendingMath
|
||||
* @notice 借贷池数学计算库
|
||||
*/
|
||||
library LendingMath {
|
||||
uint256 internal constant FACTOR_SCALE = 1e18;
|
||||
uint256 internal constant PRICE_SCALE = 1e8;
|
||||
uint256 internal constant SECONDS_PER_YEAR = 365 * 24 * 60 * 60;
|
||||
|
||||
/**
|
||||
* @notice 将本金转换为实际余额(含利息)
|
||||
* @param principal 本金(正数或负数)
|
||||
* @param index 利息索引
|
||||
* @return 实际余额
|
||||
*/
|
||||
function principalToBalance(int104 principal, uint256 index) internal pure returns (int256) {
|
||||
return int256(principal) * int256(index) / int256(FACTOR_SCALE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 将实际余额转换为本金
|
||||
* @param balance 实际余额(正数或负数)
|
||||
* @param index 利息索引
|
||||
* @return 本金
|
||||
*/
|
||||
function balanceToPrincipal(int256 balance, uint256 index) internal pure returns (int104) {
|
||||
return int104((balance * int256(FACTOR_SCALE)) / int256(index));
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算供应方本金变化和借款方本金变化
|
||||
* @dev 用于 absorb 时计算账户状态变化
|
||||
*/
|
||||
function repayAndSupplyAmount(int104 oldPrincipal, int104 newPrincipal) internal pure returns (uint104, uint104) {
|
||||
// 如果新本金小于旧本金,没有偿还或供应
|
||||
if (newPrincipal < oldPrincipal) return (0, 0);
|
||||
|
||||
if (newPrincipal <= 0) {
|
||||
// 从负数变得更接近0(偿还债务)
|
||||
return (uint104(newPrincipal - oldPrincipal), 0);
|
||||
} else if (oldPrincipal >= 0) {
|
||||
// 两个都是正数(增加存款)
|
||||
return (0, uint104(newPrincipal - oldPrincipal));
|
||||
} else {
|
||||
// 从负数变正数(偿还所有债务并存款)
|
||||
return (uint104(-oldPrincipal), uint104(newPrincipal));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算提取金额和借款金额
|
||||
* @dev 用于 withdraw/borrow 时计算账户状态变化
|
||||
*/
|
||||
function withdrawAndBorrowAmount(int104 oldPrincipal, int104 newPrincipal) internal pure returns (uint104, uint104) {
|
||||
// 如果新本金大于旧本金,没有提取或借款
|
||||
if (newPrincipal > oldPrincipal) return (0, 0);
|
||||
|
||||
if (newPrincipal >= 0) {
|
||||
// 还是正数(提取存款)
|
||||
return (uint104(oldPrincipal - newPrincipal), 0);
|
||||
} else if (oldPrincipal <= 0) {
|
||||
// 两个都是负数(增加借款)
|
||||
return (0, uint104(oldPrincipal - newPrincipal));
|
||||
} else {
|
||||
// 从正数变负数(提取所有存款并借款)
|
||||
return (uint104(oldPrincipal), uint104(-newPrincipal));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算利用率
|
||||
* @param totalSupply 总供应量
|
||||
* @param totalBorrow 总借款量
|
||||
* @return 利用率 (scaled by 1e18)
|
||||
*/
|
||||
function getUtilization(uint256 totalSupply, uint256 totalBorrow) internal pure returns (uint64) {
|
||||
if (totalSupply == 0) return 0;
|
||||
return uint64((totalBorrow * FACTOR_SCALE) / totalSupply);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算供应利率(每秒利率)
|
||||
*/
|
||||
function getSupplyRate(
|
||||
uint256 utilization,
|
||||
uint64 supplyKink,
|
||||
uint64 supplyPerSecondInterestRateSlopeLow,
|
||||
uint64 supplyPerSecondInterestRateSlopeHigh,
|
||||
uint64 supplyPerSecondInterestRateBase
|
||||
) internal pure returns (uint64) {
|
||||
if (utilization <= supplyKink) {
|
||||
return supplyPerSecondInterestRateBase + uint64((utilization * supplyPerSecondInterestRateSlopeLow) / FACTOR_SCALE);
|
||||
} else {
|
||||
uint256 excessUtil = utilization - supplyKink;
|
||||
return supplyPerSecondInterestRateBase + supplyPerSecondInterestRateSlopeLow +
|
||||
uint64((excessUtil * supplyPerSecondInterestRateSlopeHigh) / FACTOR_SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算借款利率(每秒利率)
|
||||
*/
|
||||
function getBorrowRate(
|
||||
uint256 utilization,
|
||||
uint64 borrowKink,
|
||||
uint64 borrowPerSecondInterestRateSlopeLow,
|
||||
uint64 borrowPerSecondInterestRateSlopeHigh,
|
||||
uint64 borrowPerSecondInterestRateBase
|
||||
) internal pure returns (uint64) {
|
||||
if (utilization <= borrowKink) {
|
||||
return borrowPerSecondInterestRateBase + uint64((utilization * borrowPerSecondInterestRateSlopeLow) / FACTOR_SCALE);
|
||||
} else {
|
||||
uint256 excessUtil = utilization - borrowKink;
|
||||
return borrowPerSecondInterestRateBase + borrowPerSecondInterestRateSlopeLow +
|
||||
uint64((excessUtil * borrowPerSecondInterestRateSlopeHigh) / FACTOR_SCALE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算复利后的利息累计因子
|
||||
* @param index 当前利息累计因子
|
||||
* @param interestRatePerSecond 每秒利率
|
||||
* @param timeElapsed 经过的秒数
|
||||
* @return 新的利息累计因子
|
||||
*/
|
||||
function accrueInterest(
|
||||
uint256 index,
|
||||
uint64 interestRatePerSecond,
|
||||
uint256 timeElapsed
|
||||
) internal pure returns (uint256) {
|
||||
// 优化:每秒利率直接乘以时间,只需一次除法
|
||||
uint256 interestAccrued = (index * interestRatePerSecond * timeElapsed) / FACTOR_SCALE;
|
||||
return index + interestAccrued;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算抵押品价值
|
||||
*/
|
||||
function getCollateralValue(
|
||||
uint256 collateralAmount,
|
||||
uint256 collateralPrice,
|
||||
uint8 collateralDecimals
|
||||
) internal pure returns (uint256) {
|
||||
return (collateralAmount * collateralPrice) / (10 ** collateralDecimals);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 计算借款能力
|
||||
*/
|
||||
function getBorrowCapacity(
|
||||
uint256 collateralValue,
|
||||
uint64 borrowCollateralFactor
|
||||
) internal pure returns (uint256) {
|
||||
return (collateralValue * borrowCollateralFactor) / FACTOR_SCALE;
|
||||
}
|
||||
}
|
||||
|
||||
59
contracts/ytLending/LendingStorage.sol
Normal file
59
contracts/ytLending/LendingStorage.sol
Normal file
@@ -0,0 +1,59 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "./LendingConfiguration.sol";
|
||||
|
||||
/**
|
||||
* @title LendingStorage
|
||||
* @notice 借贷池存储变量定义
|
||||
*/
|
||||
abstract contract LendingStorage is LendingConfiguration {
|
||||
|
||||
// 市场配置
|
||||
address public baseToken;
|
||||
address public baseTokenPriceFeed;
|
||||
|
||||
// 利率参数(每秒利率,已从年化利率转换)
|
||||
uint64 public supplyKink;
|
||||
uint64 public supplyPerSecondInterestRateSlopeLow;
|
||||
uint64 public supplyPerSecondInterestRateSlopeHigh;
|
||||
uint64 public supplyPerSecondInterestRateBase;
|
||||
|
||||
uint64 public borrowKink;
|
||||
uint64 public borrowPerSecondInterestRateSlopeLow;
|
||||
uint64 public borrowPerSecondInterestRateSlopeHigh;
|
||||
uint64 public borrowPerSecondInterestRateBase;
|
||||
|
||||
// 清算参数
|
||||
uint64 public storeFrontPriceFactor;
|
||||
uint64 public trackingIndexScale;
|
||||
uint104 public baseBorrowMin;
|
||||
uint104 public targetReserves;
|
||||
|
||||
// 资产映射
|
||||
mapping(address => AssetConfig) public assetConfigs;
|
||||
address[] public assetList;
|
||||
|
||||
// 用户账户信息
|
||||
struct UserBasic {
|
||||
int104 principal; // 本金(正数=存款本金,负数=借款本金)
|
||||
}
|
||||
mapping(address => UserBasic) public userBasic;
|
||||
|
||||
// 用户抵押品余额
|
||||
mapping(address => mapping(address => uint256)) public userCollateral;
|
||||
|
||||
// 总存款本金和总借款本金
|
||||
uint104 public totalSupplyBase;
|
||||
uint104 public totalBorrowBase;
|
||||
|
||||
// 利息索引
|
||||
uint256 public supplyIndex;
|
||||
uint256 public borrowIndex;
|
||||
uint256 public lastAccrualTime;
|
||||
|
||||
// 清算后的抵押品库存(不同于 reserves!)
|
||||
// reserves 通过公式动态计算:balance - totalSupply + totalBorrow
|
||||
mapping(address => uint256) public collateralReserves;
|
||||
}
|
||||
|
||||
177
contracts/ytLending/interfaces/ILending.sol
Normal file
177
contracts/ytLending/interfaces/ILending.sol
Normal file
@@ -0,0 +1,177 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @title ILending
|
||||
* @notice 借贷池核心接口
|
||||
*/
|
||||
interface ILending {
|
||||
|
||||
// ========== Events ==========
|
||||
event Supply(address indexed from, address indexed dst, uint256 amount);
|
||||
event Withdraw(address indexed src, address indexed to, uint256 amount);
|
||||
event SupplyCollateral(address indexed from, address indexed dst, address indexed asset, uint256 amount);
|
||||
event WithdrawCollateral(address indexed src, address indexed to, address indexed asset, uint256 amount);
|
||||
|
||||
/// @notice 清算债务事件
|
||||
event AbsorbDebt(address indexed absorber, address indexed borrower, uint256 basePaidOut, uint256 usdValue);
|
||||
|
||||
/// @notice 清算抵押品事件
|
||||
event AbsorbCollateral(address indexed absorber, address indexed borrower, address indexed asset, uint256 collateralAbsorbed, uint256 usdValue);
|
||||
|
||||
event BuyCollateral(address indexed buyer, address indexed asset, uint256 baseAmount, uint256 collateralAmount);
|
||||
|
||||
/// @notice 储备金提取事件
|
||||
event WithdrawReserves(address indexed to, uint256 amount);
|
||||
|
||||
// ========== Errors ==========
|
||||
error Unauthorized();
|
||||
error InsufficientBalance();
|
||||
error InsufficientCollateral();
|
||||
error BorrowTooSmall();
|
||||
error NotLiquidatable();
|
||||
error SupplyCapExceeded();
|
||||
error InvalidLiquidationFactor();
|
||||
error InsufficientReserves();
|
||||
|
||||
// ========== Core Functions ==========
|
||||
|
||||
/**
|
||||
* @notice 存入基础资产
|
||||
* @param amount 存入金额
|
||||
*/
|
||||
function supply(uint256 amount) external;
|
||||
|
||||
/**
|
||||
* @notice 取出基础资产
|
||||
* @param amount 取出金额
|
||||
*/
|
||||
function withdraw(uint256 amount) external;
|
||||
|
||||
/**
|
||||
* @notice 存入抵押品
|
||||
* @param asset 抵押品地址
|
||||
* @param amount 抵押品数量
|
||||
*/
|
||||
function supplyCollateral(address asset, uint256 amount) external;
|
||||
|
||||
/**
|
||||
* @notice 取出抵押品
|
||||
* @param asset 抵押品地址
|
||||
* @param amount 抵押品数量
|
||||
*/
|
||||
function withdrawCollateral(address asset, uint256 amount) external;
|
||||
|
||||
/**
|
||||
* @notice 借款(通过取出超过存款的基础资产实现)
|
||||
* @param amount 借款金额
|
||||
*/
|
||||
function borrow(uint256 amount) external;
|
||||
|
||||
/**
|
||||
* @notice 清算不良债务(单个)
|
||||
* @param borrower 待清算的借款人地址
|
||||
*/
|
||||
function absorb(address borrower) external;
|
||||
|
||||
/**
|
||||
* @notice 批量清算不良债务
|
||||
* @param absorber 清算发起人地址
|
||||
* @param accounts 待清算的借款人地址数组
|
||||
*/
|
||||
function absorbMultiple(address absorber, address[] calldata accounts) external;
|
||||
|
||||
/**
|
||||
* @notice 购买清算后的抵押品
|
||||
* @param asset 抵押品地址
|
||||
* @param minAmount 最小购买量
|
||||
* @param baseAmount 支付的基础资产数量
|
||||
* @param recipient 接收抵押品的地址
|
||||
*/
|
||||
function buyCollateral(address asset, uint256 minAmount, uint256 baseAmount, address recipient) external;
|
||||
|
||||
// ========== View Functions ==========
|
||||
|
||||
/**
|
||||
* @notice 获取用户基础资产余额
|
||||
* @param account 用户地址
|
||||
* @return 余额(正数=存款,负数=借款)
|
||||
*/
|
||||
function getBalance(address account) external view returns (int256);
|
||||
|
||||
/**
|
||||
* @notice 获取用户抵押品余额
|
||||
* @param account 用户地址
|
||||
* @param asset 抵押品地址
|
||||
* @return 抵押品数量
|
||||
*/
|
||||
function getCollateral(address account, address asset) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice 检查账户是否可被清算
|
||||
* @param account 用户地址
|
||||
* @return 是否可清算
|
||||
*/
|
||||
function isLiquidatable(address account) external view returns (bool);
|
||||
|
||||
/**
|
||||
* @notice 获取当前供应利率
|
||||
* @return 供应利率 (年化,scaled by 1e18)
|
||||
*/
|
||||
function getSupplyRate() external view returns (uint64);
|
||||
|
||||
/**
|
||||
* @notice 获取当前借款利率
|
||||
* @return 借款利率 (年化,scaled by 1e18)
|
||||
*/
|
||||
function getBorrowRate() external view returns (uint64);
|
||||
|
||||
/**
|
||||
* @notice 获取用户存款余额(只返回正数部分,ERC20兼容)
|
||||
* @param account 用户地址
|
||||
* @return 存款余额
|
||||
*/
|
||||
function balanceOf(address account) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice 获取用户借款余额(只返回债务部分)
|
||||
* @param account 用户地址
|
||||
* @return 借款余额
|
||||
*/
|
||||
function borrowBalanceOf(address account) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice 计算支付指定baseAmount可购买的抵押品数量
|
||||
* @param asset 抵押品地址
|
||||
* @param baseAmount 支付的基础资产数量
|
||||
* @return 可购买的抵押品数量
|
||||
*/
|
||||
function quoteCollateral(address asset, uint256 baseAmount) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice 获取协议储备金
|
||||
* @return 储备金余额(可能为负)
|
||||
*/
|
||||
function getReserves() external view returns (int256);
|
||||
|
||||
/**
|
||||
* @notice 获取抵押品库存
|
||||
* @param asset 抵押品地址
|
||||
* @return 库存数量
|
||||
*/
|
||||
function getCollateralReserves(address asset) external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice 获取市场利用率
|
||||
* @return 利用率(scaled by 1e18)
|
||||
*/
|
||||
function getUtilization() external view returns (uint256);
|
||||
|
||||
/**
|
||||
* @notice 提取协议储备金(仅 owner)
|
||||
* @param to 接收地址
|
||||
* @param amount 提取数量
|
||||
*/
|
||||
function withdrawReserves(address to, uint256 amount) external;
|
||||
}
|
||||
|
||||
21
contracts/ytLending/interfaces/IPriceFeed.sol
Normal file
21
contracts/ytLending/interfaces/IPriceFeed.sol
Normal file
@@ -0,0 +1,21 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
/**
|
||||
* @title IPriceFeed
|
||||
* @notice 价格预言机接口
|
||||
*/
|
||||
interface IPriceFeed {
|
||||
/**
|
||||
* @notice 获取资产价格
|
||||
* @return price 价格 (scaled by 1e8)
|
||||
*/
|
||||
function getPrice() external view returns (uint256 price);
|
||||
|
||||
/**
|
||||
* @notice 获取价格精度
|
||||
* @return 价格小数位数
|
||||
*/
|
||||
function decimals() external view returns (uint8);
|
||||
}
|
||||
|
||||
266
contracts/ytLp/core/YTPoolManager.sol
Normal file
266
contracts/ytLp/core/YTPoolManager.sol
Normal file
@@ -0,0 +1,266 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "../../interfaces/IYTVault.sol";
|
||||
import "../../interfaces/IYTLPToken.sol";
|
||||
import "../../interfaces/IUSDY.sol";
|
||||
|
||||
/**
|
||||
* @title YTPoolManager
|
||||
* @notice 管理ytLP的铸造和赎回,计算池子AUM
|
||||
* @dev UUPS可升级合约
|
||||
*/
|
||||
contract YTPoolManager is Initializable, UUPSUpgradeable, ReentrancyGuardUpgradeable {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
error Forbidden();
|
||||
error InvalidAddress();
|
||||
error InvalidDuration();
|
||||
error PrivateMode();
|
||||
error InvalidAmount();
|
||||
error InsufficientOutput();
|
||||
error CooldownNotPassed();
|
||||
|
||||
uint256 public constant PRICE_PRECISION = 10 ** 30;
|
||||
uint256 public constant YTLP_PRECISION = 10 ** 18;
|
||||
uint256 public constant BASIS_POINTS_DIVISOR = 10000;
|
||||
uint256 public constant MAX_COOLDOWN_DURATION = 48 hours;
|
||||
|
||||
address public gov;
|
||||
address public ytVault;
|
||||
address public usdy;
|
||||
address public ytLP;
|
||||
|
||||
uint256 public cooldownDuration;
|
||||
mapping(address => uint256) public lastAddedAt;
|
||||
|
||||
mapping(address => bool) public isHandler;
|
||||
|
||||
uint256 public aumAddition;
|
||||
uint256 public aumDeduction;
|
||||
|
||||
event AddLiquidity(
|
||||
address indexed account,
|
||||
address indexed token,
|
||||
uint256 amount,
|
||||
uint256 aumInUsdy,
|
||||
uint256 ytLPSupply,
|
||||
uint256 usdyAmount,
|
||||
uint256 mintAmount
|
||||
);
|
||||
event RemoveLiquidity(
|
||||
address indexed account,
|
||||
address indexed token,
|
||||
uint256 ytLPAmount,
|
||||
uint256 aumInUsdy,
|
||||
uint256 ytLPSupply,
|
||||
uint256 usdyAmount,
|
||||
uint256 amountOut
|
||||
);
|
||||
event CooldownDurationSet(uint256 duration);
|
||||
event HandlerSet(address indexed handler, bool isActive);
|
||||
|
||||
modifier onlyGov() {
|
||||
if (msg.sender != gov) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyHandler() {
|
||||
if (!isHandler[msg.sender] && msg.sender != gov) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 初始化合约
|
||||
* @param _ytVault YTVault合约地址
|
||||
* @param _usdy USDY代币地址
|
||||
* @param _ytLP ytLP代币地址
|
||||
* @param _cooldownDuration 冷却时间(秒)
|
||||
*/
|
||||
function initialize(
|
||||
address _ytVault,
|
||||
address _usdy,
|
||||
address _ytLP,
|
||||
uint256 _cooldownDuration
|
||||
) external initializer {
|
||||
if (_ytVault == address(0) || _usdy == address(0) || _ytLP == address(0)) revert InvalidAddress();
|
||||
if (_cooldownDuration > MAX_COOLDOWN_DURATION) revert InvalidDuration();
|
||||
|
||||
__ReentrancyGuard_init();
|
||||
__UUPSUpgradeable_init();
|
||||
|
||||
gov = msg.sender;
|
||||
ytVault = _ytVault;
|
||||
usdy = _usdy;
|
||||
ytLP = _ytLP;
|
||||
cooldownDuration = _cooldownDuration;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅gov可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyGov {}
|
||||
|
||||
function setGov(address _gov) external onlyGov {
|
||||
if (_gov == address(0)) revert InvalidAddress();
|
||||
gov = _gov;
|
||||
}
|
||||
|
||||
function setHandler(address _handler, bool _isActive) external onlyGov {
|
||||
isHandler[_handler] = _isActive;
|
||||
emit HandlerSet(_handler, _isActive);
|
||||
}
|
||||
|
||||
function setCooldownDuration(uint256 _duration) external onlyGov {
|
||||
if (_duration > MAX_COOLDOWN_DURATION) revert InvalidDuration();
|
||||
cooldownDuration = _duration;
|
||||
emit CooldownDurationSet(_duration);
|
||||
}
|
||||
|
||||
function setAumAdjustment(uint256 _addition, uint256 _deduction) external onlyGov {
|
||||
aumAddition = _addition;
|
||||
aumDeduction = _deduction;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 为指定账户添加流动性(Handler调用)
|
||||
*/
|
||||
function addLiquidityForAccount(
|
||||
address _fundingAccount,
|
||||
address _account,
|
||||
address _token,
|
||||
uint256 _amount,
|
||||
uint256 _minUsdy,
|
||||
uint256 _minYtLP
|
||||
) external onlyHandler nonReentrant returns (uint256) {
|
||||
return _addLiquidity(_fundingAccount, _account, _token, _amount, _minUsdy, _minYtLP);
|
||||
}
|
||||
|
||||
function _addLiquidity(
|
||||
address _fundingAccount,
|
||||
address _account,
|
||||
address _token,
|
||||
uint256 _amount,
|
||||
uint256 _minUsdy,
|
||||
uint256 _minYtLP
|
||||
) private returns (uint256) {
|
||||
if (_amount == 0) revert InvalidAmount();
|
||||
|
||||
uint256 aumInUsdy = getAumInUsdy(true);
|
||||
uint256 ytLPSupply = IERC20(ytLP).totalSupply();
|
||||
|
||||
IERC20(_token).safeTransferFrom(_fundingAccount, ytVault, _amount);
|
||||
uint256 usdyAmount = IYTVault(ytVault).buyUSDY(_token, address(this));
|
||||
if (usdyAmount < _minUsdy) revert InsufficientOutput();
|
||||
|
||||
uint256 mintAmount;
|
||||
if (ytLPSupply == 0) {
|
||||
mintAmount = usdyAmount;
|
||||
} else {
|
||||
mintAmount = usdyAmount * ytLPSupply / aumInUsdy;
|
||||
}
|
||||
|
||||
if (mintAmount < _minYtLP) revert InsufficientOutput();
|
||||
|
||||
IYTLPToken(ytLP).mint(_account, mintAmount);
|
||||
lastAddedAt[_account] = block.timestamp;
|
||||
|
||||
emit AddLiquidity(_account, _token, _amount, aumInUsdy, ytLPSupply, usdyAmount, mintAmount);
|
||||
|
||||
return mintAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 为指定账户移除流动性(Handler调用)
|
||||
*/
|
||||
function removeLiquidityForAccount(
|
||||
address _account,
|
||||
address _tokenOut,
|
||||
uint256 _ytLPAmount,
|
||||
uint256 _minOut,
|
||||
address _receiver
|
||||
) external onlyHandler nonReentrant returns (uint256) {
|
||||
return _removeLiquidity(_account, _tokenOut, _ytLPAmount, _minOut, _receiver);
|
||||
}
|
||||
|
||||
function _removeLiquidity(
|
||||
address _account,
|
||||
address _tokenOut,
|
||||
uint256 _ytLPAmount,
|
||||
uint256 _minOut,
|
||||
address _receiver
|
||||
) private returns (uint256) {
|
||||
if (_ytLPAmount == 0) revert InvalidAmount();
|
||||
|
||||
if (lastAddedAt[_account] + cooldownDuration > block.timestamp) revert CooldownNotPassed();
|
||||
|
||||
uint256 aumInUsdy = getAumInUsdy(false);
|
||||
uint256 ytLPSupply = IERC20(ytLP).totalSupply();
|
||||
|
||||
uint256 usdyAmount = _ytLPAmount * aumInUsdy / ytLPSupply;
|
||||
|
||||
// 先销毁ytLP
|
||||
IYTLPToken(ytLP).burn(_account, _ytLPAmount);
|
||||
|
||||
// 检查余额,只铸造差额部分
|
||||
uint256 usdyBalance = IERC20(usdy).balanceOf(address(this));
|
||||
if (usdyAmount > usdyBalance) {
|
||||
IUSDY(usdy).mint(address(this), usdyAmount - usdyBalance);
|
||||
}
|
||||
|
||||
// 转账USDY到Vault并换回代币
|
||||
IERC20(usdy).safeTransfer(ytVault, usdyAmount);
|
||||
uint256 amountOut = IYTVault(ytVault).sellUSDY(_tokenOut, _receiver);
|
||||
|
||||
if (amountOut < _minOut) revert InsufficientOutput();
|
||||
|
||||
emit RemoveLiquidity(_account, _tokenOut, _ytLPAmount, aumInUsdy, ytLPSupply, usdyAmount, amountOut);
|
||||
|
||||
return amountOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取ytLP价格
|
||||
* @param _maximise 是否取最大值
|
||||
* @return ytLP价格(18位精度)
|
||||
*/
|
||||
function getPrice(bool _maximise) external view returns (uint256) {
|
||||
uint256 aum = getAumInUsdy(_maximise);
|
||||
uint256 supply = IERC20(ytLP).totalSupply();
|
||||
|
||||
if (supply == 0) return YTLP_PRECISION;
|
||||
|
||||
return aum * YTLP_PRECISION / supply;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取池子总价值(AUM)
|
||||
* @param _maximise true=使用最大价格(添加流动性时), false=使用最小价格(移除流动性时)
|
||||
* @return USDY计价的总价值
|
||||
*/
|
||||
function getAumInUsdy(bool _maximise) public view returns (uint256) {
|
||||
uint256 aum = IYTVault(ytVault).getPoolValue(_maximise);
|
||||
|
||||
aum += aumAddition;
|
||||
if (aum > aumDeduction) {
|
||||
aum -= aumDeduction;
|
||||
} else {
|
||||
aum = 0;
|
||||
}
|
||||
|
||||
return aum;
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
|
||||
314
contracts/ytLp/core/YTPriceFeed.sol
Normal file
314
contracts/ytLp/core/YTPriceFeed.sol
Normal file
@@ -0,0 +1,314 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import "../../interfaces/IYTToken.sol";
|
||||
|
||||
/**
|
||||
* @title YTPriceFeed
|
||||
* @notice 价格读取器,直接从YT合约读取价格变量(带保护机制和价差)
|
||||
* @dev UUPS可升级合约
|
||||
*/
|
||||
contract YTPriceFeed is Initializable, UUPSUpgradeable {
|
||||
|
||||
error Forbidden();
|
||||
error MaxChangeTooHigh();
|
||||
error PriceChangeTooLarge();
|
||||
error SpreadTooHigh();
|
||||
error InvalidAddress();
|
||||
|
||||
address public gov;
|
||||
|
||||
uint256 public constant PRICE_PRECISION = 10 ** 30;
|
||||
uint256 public constant BASIS_POINTS_DIVISOR = 10000;
|
||||
uint256 public constant MAX_SPREAD_BASIS_POINTS = 200; // 最大2%价差
|
||||
|
||||
// WUSD固定价格
|
||||
address public wusdAddress;
|
||||
|
||||
// WUSD价格来源
|
||||
address public wusdPriceSource;
|
||||
|
||||
// 价格保护参数
|
||||
uint256 public maxPriceChangeBps; // 5% 最大价格变动
|
||||
|
||||
// 价差配置(每个代币可以有不同的价差)
|
||||
mapping(address => uint256) public spreadBasisPoints;
|
||||
|
||||
// 价格历史记录
|
||||
mapping(address => uint256) public lastPrice;
|
||||
|
||||
// 价格更新权限
|
||||
mapping(address => bool) public isKeeper;
|
||||
|
||||
event PriceUpdate(address indexed token, uint256 oldPrice, uint256 newPrice, uint256 timestamp);
|
||||
event SpreadUpdate(address indexed token, uint256 spreadBps);
|
||||
event KeeperSet(address indexed keeper, bool isActive);
|
||||
|
||||
modifier onlyGov() {
|
||||
if (msg.sender != gov) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyKeeper() {
|
||||
if (!isKeeper[msg.sender] && msg.sender != gov) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 初始化合约
|
||||
*/
|
||||
function initialize(address _wusdAddress) external initializer {
|
||||
__UUPSUpgradeable_init();
|
||||
if (_wusdAddress == address(0)) revert InvalidAddress();
|
||||
wusdAddress = _wusdAddress;
|
||||
gov = msg.sender;
|
||||
maxPriceChangeBps = 500; // 5% 最大价格变动
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅gov可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyGov {}
|
||||
|
||||
/**
|
||||
* @notice 设置WUSD价格来源(YTAssetVault地址)
|
||||
* @param _wusdPriceSource YTAssetVault合约地址
|
||||
*/
|
||||
function setWusdPriceSource(address _wusdPriceSource) external onlyGov {
|
||||
wusdPriceSource = _wusdPriceSource;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置keeper权限
|
||||
* @param _keeper keeper地址
|
||||
* @param _isActive 是否激活
|
||||
*/
|
||||
function setKeeper(address _keeper, bool _isActive) external onlyGov {
|
||||
isKeeper[_keeper] = _isActive;
|
||||
emit KeeperSet(_keeper, _isActive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置最大价格变动百分比
|
||||
* @param _maxPriceChangeBps 最大变动(基点)
|
||||
*/
|
||||
function setMaxPriceChangeBps(uint256 _maxPriceChangeBps) external onlyGov {
|
||||
if (_maxPriceChangeBps > 2000) revert MaxChangeTooHigh(); // 最大20%
|
||||
maxPriceChangeBps = _maxPriceChangeBps;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置代币价差
|
||||
* @param _token 代币地址
|
||||
* @param _spreadBasisPoints 价差(基点)例如:10 = 0.1%, 100 = 1%
|
||||
*/
|
||||
function setSpreadBasisPoints(address _token, uint256 _spreadBasisPoints) external onlyGov {
|
||||
if (_spreadBasisPoints > MAX_SPREAD_BASIS_POINTS) revert SpreadTooHigh();
|
||||
spreadBasisPoints[_token] = _spreadBasisPoints;
|
||||
emit SpreadUpdate(_token, _spreadBasisPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 批量设置代币价差
|
||||
* @param _tokens 代币地址数组
|
||||
* @param _spreadBasisPoints 价差数组
|
||||
*/
|
||||
function setSpreadBasisPointsForMultiple(
|
||||
address[] calldata _tokens,
|
||||
uint256[] calldata _spreadBasisPoints
|
||||
) external onlyGov {
|
||||
require(_tokens.length == _spreadBasisPoints.length, "length mismatch");
|
||||
for (uint256 i = 0; i < _tokens.length; i++) {
|
||||
if (_spreadBasisPoints[i] > MAX_SPREAD_BASIS_POINTS) revert SpreadTooHigh();
|
||||
spreadBasisPoints[_tokens[i]] = _spreadBasisPoints[i];
|
||||
emit SpreadUpdate(_tokens[i], _spreadBasisPoints[i]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 强制更新价格(紧急情况)
|
||||
* @param _token 代币地址
|
||||
* @param _price 新价格
|
||||
*/
|
||||
function forceUpdatePrice(address _token, uint256 _price) external onlyGov {
|
||||
uint256 oldPrice = lastPrice[_token];
|
||||
lastPrice[_token] = _price;
|
||||
emit PriceUpdate(_token, oldPrice, _price, block.timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取YT代币价格(带波动保护和价差)
|
||||
* @param _token 代币地址
|
||||
* @param _maximise true=最大价格(上浮价差,对协议有利), false=最小价格(下压价差,对协议有利)
|
||||
* @return 价格(30位精度)
|
||||
*
|
||||
* 使用场景:
|
||||
* - 添加流动性时AUM计算:_maximise=true(高估AUM,用户获得较少LP)
|
||||
* - 移除流动性时AUM计算:_maximise=false(低估AUM,用户获得较少代币)
|
||||
* - buyUSDY时(用户卖代币):_maximise=false(低估用户代币价值)
|
||||
* - sellUSDY时(用户买代币):_maximise=true(高估需支付的代币价值)
|
||||
* - swap时tokenIn:_maximise=false(低估输入)
|
||||
* - swap时tokenOut:_maximise=true(高估输出)
|
||||
*/
|
||||
function getPrice(address _token, bool _maximise) external view returns (uint256) {
|
||||
if (_token == wusdAddress) {
|
||||
return _getWUSDPrice();
|
||||
}
|
||||
|
||||
uint256 basePrice = _getRawPrice(_token);
|
||||
|
||||
// 价格波动检查
|
||||
_validatePriceChange(_token, basePrice);
|
||||
|
||||
// 应用价差
|
||||
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变量
|
||||
*/
|
||||
function _getRawPrice(address _token) private view returns (uint256) {
|
||||
return IYTToken(_token).ytPrice();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 从配置的YTAssetVault读取wusdPrice
|
||||
* @dev 如果未设置wusdPriceSource,返回固定价格1.0
|
||||
*/
|
||||
function _getWUSDPrice() private view returns (uint256) {
|
||||
if (wusdPriceSource == address(0)) {
|
||||
return PRICE_PRECISION; // 默认1.0
|
||||
}
|
||||
return IYTToken(wusdPriceSource).wusdPrice();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 应用价差
|
||||
* @param _token 代币地址
|
||||
* @param _basePrice 基础价格
|
||||
* @param _maximise true=上浮价格,false=下压价格
|
||||
* @return 应用价差后的价格
|
||||
*/
|
||||
function _applySpread(
|
||||
address _token,
|
||||
uint256 _basePrice,
|
||||
bool _maximise
|
||||
) private view returns (uint256) {
|
||||
uint256 spread = spreadBasisPoints[_token];
|
||||
|
||||
// 如果没有设置价差,直接返回基础价格
|
||||
if (spread == 0) {
|
||||
return _basePrice;
|
||||
}
|
||||
|
||||
if (_maximise) {
|
||||
// 上浮价格:basePrice * (1 + spread%)
|
||||
return _basePrice * (BASIS_POINTS_DIVISOR + spread) / BASIS_POINTS_DIVISOR;
|
||||
} else {
|
||||
// 下压价格:basePrice * (1 - spread%)
|
||||
return _basePrice * (BASIS_POINTS_DIVISOR - spread) / BASIS_POINTS_DIVISOR;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 验证价格变动是否在允许范围内
|
||||
*/
|
||||
function _validatePriceChange(address _token, uint256 _newPrice) private view {
|
||||
uint256 oldPrice = lastPrice[_token];
|
||||
|
||||
// 首次设置价格,跳过检查
|
||||
if (oldPrice == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 计算价格变动百分比
|
||||
uint256 priceDiff = _newPrice > oldPrice ? _newPrice - oldPrice : oldPrice - _newPrice;
|
||||
uint256 maxDiff = oldPrice * maxPriceChangeBps / BASIS_POINTS_DIVISOR;
|
||||
|
||||
if (priceDiff > maxDiff) revert PriceChangeTooLarge();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取价格详细信息
|
||||
*/
|
||||
function getPriceInfo(address _token) external view returns (
|
||||
uint256 currentPrice,
|
||||
uint256 cachedPrice,
|
||||
uint256 maxPrice,
|
||||
uint256 minPrice,
|
||||
uint256 spread
|
||||
) {
|
||||
if (_token == wusdAddress) {
|
||||
uint256 wusdPrice = _getWUSDPrice();
|
||||
currentPrice = wusdPrice;
|
||||
cachedPrice = wusdPrice;
|
||||
maxPrice = wusdPrice;
|
||||
minPrice = wusdPrice;
|
||||
spread = 0;
|
||||
} else {
|
||||
currentPrice = _getRawPrice(_token);
|
||||
cachedPrice = lastPrice[_token];
|
||||
spread = spreadBasisPoints[_token];
|
||||
maxPrice = _applySpread(_token, currentPrice, true);
|
||||
minPrice = _applySpread(_token, currentPrice, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取最大价格(上浮价差)
|
||||
*/
|
||||
function getMaxPrice(address _token) external view returns (uint256) {
|
||||
if (_token == wusdAddress) {
|
||||
// WUSD通常不需要价差,直接返回原价格
|
||||
return _getWUSDPrice();
|
||||
}
|
||||
uint256 basePrice = _getRawPrice(_token);
|
||||
_validatePriceChange(_token, basePrice);
|
||||
return _applySpread(_token, basePrice, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取最小价格(下压价差)
|
||||
*/
|
||||
function getMinPrice(address _token) external view returns (uint256) {
|
||||
if (_token == wusdAddress) {
|
||||
// WUSD通常不需要价差,直接返回原价格
|
||||
return _getWUSDPrice();
|
||||
}
|
||||
uint256 basePrice = _getRawPrice(_token);
|
||||
_validatePriceChange(_token, basePrice);
|
||||
return _applySpread(_token, basePrice, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
216
contracts/ytLp/core/YTRewardRouter.sol
Normal file
216
contracts/ytLp/core/YTRewardRouter.sol
Normal file
@@ -0,0 +1,216 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/utils/PausableUpgradeable.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "../../interfaces/IYTPoolManager.sol";
|
||||
import "../../interfaces/IYTVault.sol";
|
||||
|
||||
/**
|
||||
* @title YTRewardRouter
|
||||
* @notice 用户交互入口
|
||||
* @dev UUPS可升级合约
|
||||
*/
|
||||
contract YTRewardRouter is Initializable, UUPSUpgradeable, ReentrancyGuardUpgradeable, PausableUpgradeable {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
error Forbidden();
|
||||
error AlreadyInitialized();
|
||||
error InvalidAddress();
|
||||
error InvalidAmount();
|
||||
error InsufficientOutput();
|
||||
|
||||
address public gov;
|
||||
address public usdy;
|
||||
address public ytLP;
|
||||
address public ytPoolManager;
|
||||
address public ytVault;
|
||||
|
||||
event Swap(
|
||||
address indexed account,
|
||||
address tokenIn,
|
||||
address tokenOut,
|
||||
uint256 amountIn,
|
||||
uint256 amountOut
|
||||
);
|
||||
|
||||
modifier onlyGov() {
|
||||
if (msg.sender != gov) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 初始化合约
|
||||
* @param _usdy USDY代币地址
|
||||
* @param _ytLP ytLP代币地址
|
||||
* @param _ytPoolManager YTPoolManager地址
|
||||
* @param _ytVault YTVault地址
|
||||
*/
|
||||
function initialize(
|
||||
address _usdy,
|
||||
address _ytLP,
|
||||
address _ytPoolManager,
|
||||
address _ytVault
|
||||
) external initializer {
|
||||
if (_usdy == address(0)) revert InvalidAddress();
|
||||
if (_ytLP == address(0)) revert InvalidAddress();
|
||||
if (_ytPoolManager == address(0)) revert InvalidAddress();
|
||||
if (_ytVault == address(0)) revert InvalidAddress();
|
||||
|
||||
__ReentrancyGuard_init();
|
||||
__UUPSUpgradeable_init();
|
||||
__Pausable_init();
|
||||
|
||||
gov = msg.sender;
|
||||
|
||||
|
||||
usdy = _usdy;
|
||||
ytLP = _ytLP;
|
||||
ytPoolManager = _ytPoolManager;
|
||||
ytVault = _ytVault;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅gov可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyGov {}
|
||||
|
||||
/**
|
||||
* @notice 暂停合约(仅gov可调用)
|
||||
* @dev 暂停后,所有资金流动操作将被禁止
|
||||
*/
|
||||
function pause() external onlyGov {
|
||||
_pause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 恢复合约(仅gov可调用)
|
||||
*/
|
||||
function unpause() external onlyGov {
|
||||
_unpause();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 添加流动性
|
||||
* @param _token YT代币或WUSD地址
|
||||
* @param _amount 代币数量
|
||||
* @param _minUsdy 最小USDY数量
|
||||
* @param _minYtLP 最小ytLP数量
|
||||
* @return ytLPAmount 获得的ytLP数量
|
||||
*/
|
||||
function addLiquidity(
|
||||
address _token,
|
||||
uint256 _amount,
|
||||
uint256 _minUsdy,
|
||||
uint256 _minYtLP
|
||||
) external nonReentrant whenNotPaused returns (uint256) {
|
||||
if (_amount == 0) revert InvalidAmount();
|
||||
|
||||
address account = msg.sender;
|
||||
|
||||
IERC20(_token).safeTransferFrom(account, address(this), _amount);
|
||||
IERC20(_token).approve(ytPoolManager, _amount);
|
||||
|
||||
uint256 ytLPAmount = IYTPoolManager(ytPoolManager).addLiquidityForAccount(
|
||||
address(this),
|
||||
account,
|
||||
_token,
|
||||
_amount,
|
||||
_minUsdy,
|
||||
_minYtLP
|
||||
);
|
||||
|
||||
return ytLPAmount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 移除流动性
|
||||
* @param _tokenOut 输出代币地址
|
||||
* @param _ytLPAmount ytLP数量
|
||||
* @param _minOut 最小输出数量
|
||||
* @param _receiver 接收地址
|
||||
* @return amountOut 获得的代币数量
|
||||
*/
|
||||
function removeLiquidity(
|
||||
address _tokenOut,
|
||||
uint256 _ytLPAmount,
|
||||
uint256 _minOut,
|
||||
address _receiver
|
||||
) external nonReentrant whenNotPaused returns (uint256) {
|
||||
if (_ytLPAmount == 0) revert InvalidAmount();
|
||||
|
||||
address account = msg.sender;
|
||||
|
||||
uint256 amountOut = IYTPoolManager(ytPoolManager).removeLiquidityForAccount(
|
||||
account,
|
||||
_tokenOut,
|
||||
_ytLPAmount,
|
||||
_minOut,
|
||||
_receiver
|
||||
);
|
||||
|
||||
return amountOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice YT代币互换
|
||||
* @param _tokenIn 输入代币地址
|
||||
* @param _tokenOut 输出代币地址
|
||||
* @param _amountIn 输入数量
|
||||
* @param _minOut 最小输出数量
|
||||
* @param _receiver 接收地址
|
||||
* @return amountOut 获得的代币数量
|
||||
*/
|
||||
function swapYT(
|
||||
address _tokenIn,
|
||||
address _tokenOut,
|
||||
uint256 _amountIn,
|
||||
uint256 _minOut,
|
||||
address _receiver
|
||||
) external nonReentrant whenNotPaused returns (uint256) {
|
||||
if (_amountIn == 0) revert InvalidAmount();
|
||||
|
||||
address account = msg.sender;
|
||||
|
||||
IERC20(_tokenIn).safeTransferFrom(account, ytVault, _amountIn);
|
||||
|
||||
uint256 amountOut = IYTVault(ytVault).swap(_tokenIn, _tokenOut, _receiver);
|
||||
|
||||
if (amountOut < _minOut) revert InsufficientOutput();
|
||||
|
||||
emit Swap(account, _tokenIn, _tokenOut, _amountIn, amountOut);
|
||||
|
||||
return amountOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取ytLP价格
|
||||
* @return ytLP价格(18位精度)
|
||||
*/
|
||||
function getYtLPPrice() external view returns (uint256) {
|
||||
return IYTPoolManager(ytPoolManager).getPrice(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取账户价值
|
||||
* @param _account 账户地址
|
||||
* @return 账户持有的ytLP价值(USDY计价)
|
||||
*/
|
||||
function getAccountValue(address _account) external view returns (uint256) {
|
||||
uint256 ytLPBalance = IERC20(ytLP).balanceOf(_account);
|
||||
uint256 ytLPPrice = IYTPoolManager(ytPoolManager).getPrice(true);
|
||||
return ytLPBalance * ytLPPrice / (10 ** 18);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
|
||||
626
contracts/ytLp/core/YTVault.sol
Normal file
626
contracts/ytLp/core/YTVault.sol
Normal file
@@ -0,0 +1,626 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/utils/ReentrancyGuardUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
|
||||
import "@openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol";
|
||||
import "../../interfaces/IUSDY.sol";
|
||||
import "../../interfaces/IYTPriceFeed.sol";
|
||||
|
||||
/**
|
||||
* @title YTVault
|
||||
* @notice 核心资金池,处理YT代币的存储、交换和动态手续费
|
||||
* @dev UUPS可升级合约
|
||||
*/
|
||||
contract YTVault is Initializable, UUPSUpgradeable, ReentrancyGuardUpgradeable {
|
||||
using SafeERC20 for IERC20;
|
||||
|
||||
error Forbidden();
|
||||
error OnlyPoolManager();
|
||||
error NotSwapper();
|
||||
error EmergencyMode();
|
||||
error InvalidAddress();
|
||||
error TokenNotWhitelisted();
|
||||
error InvalidFee();
|
||||
error NotInEmergency();
|
||||
error SlippageTooHigh();
|
||||
error SwapDisabled();
|
||||
error InvalidAmount();
|
||||
error InsufficientPool();
|
||||
error SameToken();
|
||||
error AmountExceedsLimit();
|
||||
error MaxUSDYExceeded();
|
||||
error InsufficientUSDYAmount();
|
||||
error InvalidPoolAmount();
|
||||
error DailyLimitExceeded();
|
||||
|
||||
uint256 public constant PRICE_PRECISION = 10 ** 30;
|
||||
uint256 public constant BASIS_POINTS_DIVISOR = 10000;
|
||||
uint256 public constant USDY_DECIMALS = 18;
|
||||
|
||||
address public gov;
|
||||
address public ytPoolManager;
|
||||
address public priceFeed;
|
||||
address public usdy;
|
||||
|
||||
mapping(address => bool) public isSwapper; // 授权的swap调用者
|
||||
|
||||
bool public isSwapEnabled;
|
||||
bool public emergencyMode;
|
||||
|
||||
// 代币白名单
|
||||
address[] public allWhitelistedTokens;
|
||||
mapping(address => bool) public whitelistedTokens;
|
||||
mapping(address => bool) public stableTokens; // 稳定币标记
|
||||
mapping(address => uint256) public tokenDecimals;
|
||||
mapping(address => uint256) public tokenWeights;
|
||||
uint256 public totalTokenWeights;
|
||||
|
||||
// 池子资产
|
||||
mapping(address => uint256) public poolAmounts;
|
||||
mapping(address => uint256) public tokenBalances; // 跟踪实际代币余额
|
||||
|
||||
// USDY债务追踪(用于动态手续费)
|
||||
mapping(address => uint256) public usdyAmounts;
|
||||
mapping(address => uint256) public maxUsdyAmounts;
|
||||
|
||||
// 手续费配置
|
||||
uint256 public swapFeeBasisPoints;
|
||||
uint256 public stableSwapFeeBasisPoints;
|
||||
uint256 public taxBasisPoints;
|
||||
uint256 public stableTaxBasisPoints;
|
||||
bool public hasDynamicFees;
|
||||
|
||||
// 全局滑点保护
|
||||
uint256 public maxSwapSlippageBps; // 10% 最大滑点
|
||||
|
||||
// 单笔交易限额
|
||||
mapping(address => uint256) public maxSwapAmount;
|
||||
|
||||
event Swap(
|
||||
address indexed account,
|
||||
address indexed tokenIn,
|
||||
address indexed tokenOut,
|
||||
uint256 amountIn,
|
||||
uint256 amountOut,
|
||||
uint256 feeBasisPoints
|
||||
);
|
||||
event AddLiquidity(
|
||||
address indexed account,
|
||||
address indexed token,
|
||||
uint256 amount,
|
||||
uint256 usdyAmount
|
||||
);
|
||||
event RemoveLiquidity(
|
||||
address indexed account,
|
||||
address indexed token,
|
||||
uint256 usdyAmount,
|
||||
uint256 amountOut
|
||||
);
|
||||
event EmergencyModeSet(bool enabled);
|
||||
event SwapEnabledSet(bool enabled);
|
||||
|
||||
modifier onlyGov() {
|
||||
if (msg.sender != gov) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlyPoolManager() {
|
||||
if (msg.sender != ytPoolManager) revert OnlyPoolManager();
|
||||
_;
|
||||
}
|
||||
|
||||
modifier onlySwapper() {
|
||||
if (!isSwapper[msg.sender] && msg.sender != ytPoolManager) revert NotSwapper();
|
||||
_;
|
||||
}
|
||||
|
||||
modifier notInEmergency() {
|
||||
if (emergencyMode) revert EmergencyMode();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 初始化合约
|
||||
* @param _usdy USDY代币地址
|
||||
* @param _priceFeed 价格预言机地址
|
||||
*/
|
||||
function initialize(address _usdy, address _priceFeed) external initializer {
|
||||
if (_usdy == address(0) || _priceFeed == address(0)) revert InvalidAddress();
|
||||
|
||||
__ReentrancyGuard_init();
|
||||
__UUPSUpgradeable_init();
|
||||
|
||||
gov = msg.sender;
|
||||
usdy = _usdy;
|
||||
priceFeed = _priceFeed;
|
||||
|
||||
// 初始化默认值
|
||||
isSwapEnabled = true;
|
||||
emergencyMode = false;
|
||||
swapFeeBasisPoints = 30;
|
||||
stableSwapFeeBasisPoints = 4;
|
||||
taxBasisPoints = 50;
|
||||
stableTaxBasisPoints = 20;
|
||||
hasDynamicFees = true;
|
||||
maxSwapSlippageBps = 1000; // 10% 最大滑点
|
||||
|
||||
// 将 USDY 标记为稳定币,这样 USDY ↔ 稳定币的互换可以享受低费率
|
||||
stableTokens[_usdy] = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅gov可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyGov {}
|
||||
|
||||
function setGov(address _gov) external onlyGov {
|
||||
if (_gov == address(0)) revert InvalidAddress();
|
||||
gov = _gov;
|
||||
}
|
||||
|
||||
function setPoolManager(address _manager) external onlyGov {
|
||||
if (_manager == address(0)) revert InvalidAddress();
|
||||
ytPoolManager = _manager;
|
||||
}
|
||||
|
||||
function setSwapper(address _swapper, bool _isActive) external onlyGov {
|
||||
if (_swapper == address(0)) revert InvalidAddress();
|
||||
isSwapper[_swapper] = _isActive;
|
||||
}
|
||||
|
||||
function setWhitelistedToken(
|
||||
address _token,
|
||||
uint256 _decimals,
|
||||
uint256 _weight,
|
||||
uint256 _maxUsdyAmount,
|
||||
bool _isStable
|
||||
) external onlyGov {
|
||||
if (_token == address(0)) revert InvalidAddress();
|
||||
|
||||
if (!whitelistedTokens[_token]) {
|
||||
allWhitelistedTokens.push(_token);
|
||||
whitelistedTokens[_token] = true;
|
||||
}
|
||||
|
||||
totalTokenWeights = totalTokenWeights - tokenWeights[_token] + _weight;
|
||||
tokenDecimals[_token] = _decimals;
|
||||
tokenWeights[_token] = _weight;
|
||||
maxUsdyAmounts[_token] = _maxUsdyAmount;
|
||||
stableTokens[_token] = _isStable;
|
||||
}
|
||||
|
||||
function clearWhitelistedToken(address _token) external onlyGov {
|
||||
if (!whitelistedTokens[_token]) revert TokenNotWhitelisted();
|
||||
totalTokenWeights = totalTokenWeights - tokenWeights[_token];
|
||||
delete whitelistedTokens[_token];
|
||||
delete stableTokens[_token];
|
||||
delete tokenDecimals[_token];
|
||||
delete tokenWeights[_token];
|
||||
delete maxUsdyAmounts[_token];
|
||||
}
|
||||
|
||||
function setSwapFees(
|
||||
uint256 _swapFee,
|
||||
uint256 _stableSwapFee,
|
||||
uint256 _taxBasisPoints,
|
||||
uint256 _stableTaxBasisPoints
|
||||
) external onlyGov {
|
||||
if (_swapFee > 100 || _stableSwapFee > 50) revert InvalidFee();
|
||||
swapFeeBasisPoints = _swapFee;
|
||||
stableSwapFeeBasisPoints = _stableSwapFee;
|
||||
taxBasisPoints = _taxBasisPoints;
|
||||
stableTaxBasisPoints = _stableTaxBasisPoints;
|
||||
}
|
||||
|
||||
function setDynamicFees(bool _hasDynamicFees) external onlyGov {
|
||||
hasDynamicFees = _hasDynamicFees;
|
||||
}
|
||||
|
||||
function setEmergencyMode(bool _emergencyMode) external onlyGov {
|
||||
emergencyMode = _emergencyMode;
|
||||
emit EmergencyModeSet(_emergencyMode);
|
||||
}
|
||||
|
||||
function setSwapEnabled(bool _isSwapEnabled) external onlyGov {
|
||||
isSwapEnabled = _isSwapEnabled;
|
||||
emit SwapEnabledSet(_isSwapEnabled);
|
||||
}
|
||||
|
||||
function withdrawToken(address _token, address _receiver, uint256 _amount) external onlyGov {
|
||||
if (!emergencyMode) revert NotInEmergency();
|
||||
IERC20(_token).safeTransfer(_receiver, _amount);
|
||||
_updateTokenBalance(_token);
|
||||
}
|
||||
|
||||
function setMaxSwapSlippageBps(uint256 _slippageBps) external onlyGov {
|
||||
if (_slippageBps > 2000) revert SlippageTooHigh(); // 最大20%
|
||||
maxSwapSlippageBps = _slippageBps;
|
||||
}
|
||||
|
||||
function setMaxSwapAmount(address _token, uint256 _amount) external onlyGov {
|
||||
maxSwapAmount[_token] = _amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 用YT代币购买USDY(添加流动性时调用)
|
||||
* @param _token YT代币地址
|
||||
* @param _receiver USDY接收地址
|
||||
* @return usdyAmountAfterFees 实际获得的USDY数量
|
||||
*/
|
||||
function buyUSDY(address _token, address _receiver)
|
||||
external
|
||||
onlyPoolManager
|
||||
nonReentrant
|
||||
notInEmergency
|
||||
returns (uint256)
|
||||
{
|
||||
if (!whitelistedTokens[_token]) revert TokenNotWhitelisted();
|
||||
if (!isSwapEnabled) revert SwapDisabled();
|
||||
|
||||
uint256 tokenAmount = _transferIn(_token);
|
||||
if (tokenAmount == 0) revert InvalidAmount();
|
||||
|
||||
uint256 price = _getPrice(_token, false);
|
||||
uint256 usdyAmount = tokenAmount * price / PRICE_PRECISION;
|
||||
usdyAmount = _adjustForDecimals(usdyAmount, _token, usdy);
|
||||
if (usdyAmount == 0) revert InvalidAmount();
|
||||
|
||||
uint256 feeBasisPoints = _getSwapFeeBasisPoints(_token, usdy, usdyAmount);
|
||||
uint256 feeAmount = tokenAmount * feeBasisPoints / BASIS_POINTS_DIVISOR;
|
||||
uint256 amountAfterFees = tokenAmount - feeAmount;
|
||||
|
||||
uint256 usdyAmountAfterFees = amountAfterFees * price / PRICE_PRECISION;
|
||||
usdyAmountAfterFees = _adjustForDecimals(usdyAmountAfterFees, _token, usdy);
|
||||
|
||||
// 手续费直接留在池子中:全部代币加入poolAmount,但只铸造扣费后的USDY
|
||||
_increasePoolAmount(_token, tokenAmount);
|
||||
_increaseUsdyAmount(_token, usdyAmountAfterFees);
|
||||
|
||||
IUSDY(usdy).mint(_receiver, usdyAmountAfterFees);
|
||||
|
||||
emit AddLiquidity(_receiver, _token, tokenAmount, usdyAmountAfterFees);
|
||||
|
||||
return usdyAmountAfterFees;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 用USDY卖出换取YT代币(移除流动性时调用)
|
||||
* @param _token YT代币地址
|
||||
* @param _receiver YT代币接收地址
|
||||
* @return amountOutAfterFees 实际获得的YT代币数量
|
||||
*/
|
||||
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();
|
||||
|
||||
// 计算实际转出的代币对应的USDY价值(用于减少usdyAmount记账)
|
||||
uint256 usdyAmountOut = amountOut * price / PRICE_PRECISION;
|
||||
usdyAmountOut = _adjustForDecimals(usdyAmountOut, _token, usdy);
|
||||
|
||||
// 手续费留在池子:只减少实际转出的部分
|
||||
_decreasePoolAmount(_token, amountOut);
|
||||
_decreaseUsdyAmount(_token, usdyAmountOut);
|
||||
|
||||
// 销毁USDY
|
||||
IUSDY(usdy).burn(address(this), usdyAmount);
|
||||
|
||||
// 转出代币
|
||||
IERC20(_token).safeTransfer(_receiver, amountOut);
|
||||
_updateTokenBalance(_token);
|
||||
|
||||
emit RemoveLiquidity(_receiver, _token, usdyAmount, amountOut);
|
||||
|
||||
return amountOut;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice YT代币互换
|
||||
* @param _tokenIn 输入代币地址
|
||||
* @param _tokenOut 输出代币地址
|
||||
* @param _receiver 接收地址
|
||||
* @return amountOutAfterFees 实际获得的输出代币数量
|
||||
*/
|
||||
function swap(
|
||||
address _tokenIn,
|
||||
address _tokenOut,
|
||||
address _receiver
|
||||
) external onlySwapper nonReentrant notInEmergency returns (uint256) {
|
||||
if (!isSwapEnabled) revert SwapDisabled();
|
||||
if (!whitelistedTokens[_tokenIn]) revert TokenNotWhitelisted();
|
||||
if (!whitelistedTokens[_tokenOut]) revert TokenNotWhitelisted();
|
||||
if (_tokenIn == _tokenOut) revert SameToken();
|
||||
|
||||
uint256 amountIn = _transferIn(_tokenIn);
|
||||
if (amountIn == 0) revert InvalidAmount();
|
||||
|
||||
// 检查单笔交易限额
|
||||
if (maxSwapAmount[_tokenIn] > 0) {
|
||||
if (amountIn > maxSwapAmount[_tokenIn]) revert AmountExceedsLimit();
|
||||
}
|
||||
|
||||
uint256 priceIn = _getPrice(_tokenIn, false);
|
||||
uint256 priceOut = _getPrice(_tokenOut, true);
|
||||
|
||||
uint256 usdyAmount = amountIn * priceIn / PRICE_PRECISION;
|
||||
usdyAmount = _adjustForDecimals(usdyAmount, _tokenIn, usdy);
|
||||
|
||||
uint256 amountOut = usdyAmount * PRICE_PRECISION / priceOut;
|
||||
amountOut = _adjustForDecimals(amountOut, usdy, _tokenOut);
|
||||
|
||||
uint256 feeBasisPoints = _getSwapFeeBasisPoints(_tokenIn, _tokenOut, usdyAmount);
|
||||
uint256 amountOutAfterFees = amountOut * (BASIS_POINTS_DIVISOR - feeBasisPoints) / BASIS_POINTS_DIVISOR;
|
||||
|
||||
if (amountOutAfterFees == 0) revert InvalidAmount();
|
||||
if (poolAmounts[_tokenOut] < amountOutAfterFees) revert InsufficientPool();
|
||||
|
||||
// 全局滑点保护
|
||||
_validateSwapSlippage(amountIn, amountOutAfterFees, priceIn, priceOut);
|
||||
|
||||
_increasePoolAmount(_tokenIn, amountIn);
|
||||
_decreasePoolAmount(_tokenOut, amountOutAfterFees);
|
||||
|
||||
_increaseUsdyAmount(_tokenIn, usdyAmount);
|
||||
_decreaseUsdyAmount(_tokenOut, usdyAmount);
|
||||
|
||||
IERC20(_tokenOut).safeTransfer(_receiver, amountOutAfterFees);
|
||||
_updateTokenBalance(_tokenOut);
|
||||
|
||||
emit Swap(msg.sender, _tokenIn, _tokenOut, amountIn, amountOutAfterFees, feeBasisPoints);
|
||||
|
||||
return amountOutAfterFees;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取代币价格(带价差)
|
||||
* @param _token 代币地址
|
||||
* @param _maximise true=最大价格, false=最小价格
|
||||
* @return 价格(30位精度)
|
||||
*/
|
||||
function getPrice(address _token, bool _maximise) external view returns (uint256) {
|
||||
return _getPrice(_token, _maximise);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取最大价格
|
||||
*/
|
||||
function getMaxPrice(address _token) external view returns (uint256) {
|
||||
return _getPrice(_token, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取最小价格
|
||||
*/
|
||||
function getMinPrice(address _token) external view returns (uint256) {
|
||||
return _getPrice(_token, false);
|
||||
}
|
||||
|
||||
function getAllPoolTokens() external view returns (address[] memory) {
|
||||
return allWhitelistedTokens;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取池子总价值
|
||||
* @param _maximise true=使用最大价格(对协议有利), false=使用最小价格(对用户有利)
|
||||
* @return 池子总价值(USDY计价)
|
||||
*/
|
||||
function getPoolValue(bool _maximise) external view returns (uint256) {
|
||||
uint256 totalValue = 0;
|
||||
for (uint256 i = 0; i < allWhitelistedTokens.length; i++) {
|
||||
address token = allWhitelistedTokens[i];
|
||||
if (!whitelistedTokens[token]) continue;
|
||||
|
||||
uint256 amount = poolAmounts[token];
|
||||
uint256 price = _getPrice(token, _maximise);
|
||||
uint256 value = amount * price / PRICE_PRECISION;
|
||||
value = _adjustForDecimals(value, token, usdy);
|
||||
totalValue += value;
|
||||
}
|
||||
return totalValue;
|
||||
}
|
||||
|
||||
function getTargetUsdyAmount(address _token) public view returns (uint256) {
|
||||
uint256 supply = IERC20(usdy).totalSupply();
|
||||
if (supply == 0) { return 0; }
|
||||
uint256 weight = tokenWeights[_token];
|
||||
return weight * supply / totalTokenWeights;
|
||||
}
|
||||
|
||||
function _increaseUsdyAmount(address _token, uint256 _amount) private {
|
||||
usdyAmounts[_token] = usdyAmounts[_token] + _amount;
|
||||
uint256 maxUsdyAmount = maxUsdyAmounts[_token];
|
||||
if (maxUsdyAmount != 0) {
|
||||
if (usdyAmounts[_token] > maxUsdyAmount) revert MaxUSDYExceeded();
|
||||
}
|
||||
}
|
||||
|
||||
function _decreaseUsdyAmount(address _token, uint256 _amount) private {
|
||||
uint256 value = usdyAmounts[_token];
|
||||
if (value < _amount) revert InsufficientUSDYAmount();
|
||||
usdyAmounts[_token] = value - _amount;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取swap手续费率(公开方法,供前端调用)
|
||||
* @param _tokenIn 输入代币
|
||||
* @param _tokenOut 输出代币
|
||||
* @param _usdyAmount USDY数量
|
||||
* @return 手续费率(basis points)
|
||||
*/
|
||||
function getSwapFeeBasisPoints(
|
||||
address _tokenIn,
|
||||
address _tokenOut,
|
||||
uint256 _usdyAmount
|
||||
) public view returns (uint256) {
|
||||
return _getSwapFeeBasisPoints(_tokenIn, _tokenOut, _usdyAmount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取赎回手续费率(sellUSDY时使用)
|
||||
* @param _token 代币地址
|
||||
* @param _usdyAmount USDY数量
|
||||
* @return 手续费率(basis points)
|
||||
*/
|
||||
function getRedemptionFeeBasisPoints(
|
||||
address _token,
|
||||
uint256 _usdyAmount
|
||||
) public view returns (uint256) {
|
||||
return _getSwapFeeBasisPoints(usdy, _token, _usdyAmount);
|
||||
}
|
||||
|
||||
function _getSwapFeeBasisPoints(
|
||||
address _tokenIn,
|
||||
address _tokenOut,
|
||||
uint256 _usdyAmount
|
||||
) private view returns (uint256) {
|
||||
// 稳定币交换是指两个代币都是稳定币(如 WUSD <-> USDC)
|
||||
bool isStableSwap = stableTokens[_tokenIn] && stableTokens[_tokenOut];
|
||||
uint256 baseBps = isStableSwap ? stableSwapFeeBasisPoints : swapFeeBasisPoints;
|
||||
uint256 taxBps = isStableSwap ? stableTaxBasisPoints : taxBasisPoints;
|
||||
|
||||
if (!hasDynamicFees) {
|
||||
return baseBps;
|
||||
}
|
||||
|
||||
uint256 feesBasisPoints0 = getFeeBasisPoints(_tokenIn, _usdyAmount, baseBps, taxBps, true);
|
||||
uint256 feesBasisPoints1 = getFeeBasisPoints(_tokenOut, _usdyAmount, baseBps, taxBps, false);
|
||||
|
||||
return feesBasisPoints0 > feesBasisPoints1 ? feesBasisPoints0 : feesBasisPoints1;
|
||||
}
|
||||
|
||||
function getFeeBasisPoints(
|
||||
address _token,
|
||||
uint256 _usdyDelta,
|
||||
uint256 _feeBasisPoints,
|
||||
uint256 _taxBasisPoints,
|
||||
bool _increment
|
||||
) public view returns (uint256) {
|
||||
if (!hasDynamicFees) { return _feeBasisPoints; }
|
||||
|
||||
uint256 initialAmount = usdyAmounts[_token];
|
||||
uint256 nextAmount = initialAmount + _usdyDelta;
|
||||
if (!_increment) {
|
||||
nextAmount = _usdyDelta > initialAmount ? 0 : initialAmount - _usdyDelta;
|
||||
}
|
||||
|
||||
uint256 targetAmount = getTargetUsdyAmount(_token);
|
||||
if (targetAmount == 0) { return _feeBasisPoints; }
|
||||
|
||||
uint256 initialDiff = initialAmount > targetAmount
|
||||
? initialAmount - targetAmount
|
||||
: targetAmount - initialAmount;
|
||||
uint256 nextDiff = nextAmount > targetAmount
|
||||
? nextAmount - targetAmount
|
||||
: targetAmount - nextAmount;
|
||||
|
||||
// 改善平衡 → 降低手续费
|
||||
if (nextDiff < initialDiff) {
|
||||
uint256 rebateBps = _taxBasisPoints * initialDiff / targetAmount;
|
||||
return rebateBps > _feeBasisPoints ? 0 : _feeBasisPoints - rebateBps;
|
||||
}
|
||||
|
||||
// 恶化平衡 → 提高手续费
|
||||
uint256 averageDiff = (initialDiff + nextDiff) / 2;
|
||||
if (averageDiff > targetAmount) {
|
||||
averageDiff = targetAmount;
|
||||
}
|
||||
uint256 taxBps = _taxBasisPoints * averageDiff / targetAmount;
|
||||
return _feeBasisPoints + taxBps;
|
||||
}
|
||||
|
||||
function _transferIn(address _token) private returns (uint256) {
|
||||
uint256 prevBalance = tokenBalances[_token];
|
||||
uint256 nextBalance = IERC20(_token).balanceOf(address(this));
|
||||
tokenBalances[_token] = nextBalance;
|
||||
return nextBalance - prevBalance;
|
||||
}
|
||||
|
||||
function _updateTokenBalance(address _token) private {
|
||||
tokenBalances[_token] = IERC20(_token).balanceOf(address(this));
|
||||
}
|
||||
|
||||
function _increasePoolAmount(address _token, uint256 _amount) private {
|
||||
poolAmounts[_token] += _amount;
|
||||
_validatePoolAmount(_token);
|
||||
}
|
||||
|
||||
function _decreasePoolAmount(address _token, uint256 _amount) private {
|
||||
if (poolAmounts[_token] < _amount) revert InsufficientPool();
|
||||
poolAmounts[_token] -= _amount;
|
||||
}
|
||||
|
||||
function _validatePoolAmount(address _token) private view {
|
||||
if (poolAmounts[_token] > tokenBalances[_token]) revert InvalidPoolAmount();
|
||||
}
|
||||
|
||||
function _validateSwapSlippage(
|
||||
uint256 _amountIn,
|
||||
uint256 _amountOut,
|
||||
uint256 _priceIn,
|
||||
uint256 _priceOut
|
||||
) private view {
|
||||
// 计算预期输出(不含手续费)
|
||||
uint256 expectedOut = _amountIn * _priceIn / _priceOut;
|
||||
|
||||
// 计算实际滑点
|
||||
if (expectedOut > _amountOut) {
|
||||
uint256 slippage = (expectedOut - _amountOut) * BASIS_POINTS_DIVISOR / expectedOut;
|
||||
if (slippage > maxSwapSlippageBps) revert SlippageTooHigh();
|
||||
}
|
||||
}
|
||||
|
||||
function _getPrice(address _token, bool _maximise) private view returns (uint256) {
|
||||
return IYTPriceFeed(priceFeed).getPrice(_token, _maximise);
|
||||
}
|
||||
|
||||
function _adjustForDecimals(
|
||||
uint256 _amount,
|
||||
address _tokenFrom,
|
||||
address _tokenTo
|
||||
) private view returns (uint256) {
|
||||
uint256 decimalsFrom = _tokenFrom == usdy ? USDY_DECIMALS : tokenDecimals[_tokenFrom];
|
||||
uint256 decimalsTo = _tokenTo == usdy ? USDY_DECIMALS : tokenDecimals[_tokenTo];
|
||||
|
||||
if (decimalsFrom == decimalsTo) {
|
||||
return _amount;
|
||||
}
|
||||
|
||||
if (decimalsFrom > decimalsTo) {
|
||||
return _amount / (10 ** (decimalsFrom - decimalsTo));
|
||||
}
|
||||
|
||||
return _amount * (10 ** (decimalsTo - decimalsFrom));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
|
||||
87
contracts/ytLp/tokens/USDY.sol
Normal file
87
contracts/ytLp/tokens/USDY.sol
Normal file
@@ -0,0 +1,87 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
|
||||
/**
|
||||
* @title USDY Token
|
||||
* @notice 统一计价代币
|
||||
* @dev 只有授权的Vault可以铸造和销毁,UUPS可升级合约
|
||||
*/
|
||||
contract USDY is Initializable, ERC20Upgradeable, OwnableUpgradeable, UUPSUpgradeable {
|
||||
|
||||
error Forbidden();
|
||||
error InvalidVault();
|
||||
|
||||
mapping(address => bool) public vaults;
|
||||
|
||||
event VaultAdded(address indexed vault);
|
||||
event VaultRemoved(address indexed vault);
|
||||
|
||||
modifier onlyVault() {
|
||||
if (!vaults[msg.sender]) revert Forbidden();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 初始化合约
|
||||
*/
|
||||
function initialize() external initializer {
|
||||
__ERC20_init("YT USD", "USDY");
|
||||
__Ownable_init(msg.sender);
|
||||
__UUPSUpgradeable_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅owner可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
||||
|
||||
/**
|
||||
* @notice 添加授权的Vault地址
|
||||
* @param _vault Vault合约地址
|
||||
*/
|
||||
function addVault(address _vault) external onlyOwner {
|
||||
if (_vault == address(0)) revert InvalidVault();
|
||||
vaults[_vault] = true;
|
||||
emit VaultAdded(_vault);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 移除授权的Vault地址
|
||||
* @param _vault Vault合约地址
|
||||
*/
|
||||
function removeVault(address _vault) external onlyOwner {
|
||||
vaults[_vault] = false;
|
||||
emit VaultRemoved(_vault);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 铸造USDY代币
|
||||
* @param _account 接收地址
|
||||
* @param _amount 铸造数量
|
||||
*/
|
||||
function mint(address _account, uint256 _amount) external onlyVault {
|
||||
_mint(_account, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 销毁USDY代币
|
||||
* @param _account 销毁地址
|
||||
* @param _amount 销毁数量
|
||||
*/
|
||||
function burn(address _account, uint256 _amount) external onlyVault {
|
||||
_burn(_account, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
|
||||
54
contracts/ytLp/tokens/WUSD.sol
Normal file
54
contracts/ytLp/tokens/WUSD.sol
Normal file
@@ -0,0 +1,54 @@
|
||||
// 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 {
|
||||
|
||||
/**
|
||||
* @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;
|
||||
}
|
||||
78
contracts/ytLp/tokens/YTLPToken.sol
Normal file
78
contracts/ytLp/tokens/YTLPToken.sol
Normal file
@@ -0,0 +1,78 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts-upgradeable/token/ERC20/ERC20Upgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/access/OwnableUpgradeable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/Initializable.sol";
|
||||
import "@openzeppelin/contracts-upgradeable/proxy/utils/UUPSUpgradeable.sol";
|
||||
|
||||
/**
|
||||
* @title YTLPToken
|
||||
* @notice LP代币,代表用户在池子中的份额
|
||||
* @dev 只有授权的Minter(YTPoolManager)可以铸造和销毁,UUPS可升级合约
|
||||
*/
|
||||
contract YTLPToken is Initializable, ERC20Upgradeable, OwnableUpgradeable, UUPSUpgradeable {
|
||||
|
||||
error NotMinter();
|
||||
error InvalidMinter();
|
||||
|
||||
mapping(address => bool) public isMinter;
|
||||
|
||||
event MinterSet(address indexed minter, bool isActive);
|
||||
|
||||
/**
|
||||
* @notice 初始化合约
|
||||
*/
|
||||
function initialize() external initializer {
|
||||
__ERC20_init("YT Liquidity Provider", "ytLP");
|
||||
__Ownable_init(msg.sender);
|
||||
__UUPSUpgradeable_init();
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 授权升级(仅owner可调用)
|
||||
* @param newImplementation 新实现合约地址
|
||||
*/
|
||||
function _authorizeUpgrade(address newImplementation) internal override onlyOwner {}
|
||||
|
||||
modifier onlyMinter() {
|
||||
if (!isMinter[msg.sender]) revert NotMinter();
|
||||
_;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置铸造权限
|
||||
* @param _minter 铸造者地址
|
||||
* @param _isActive 是否激活
|
||||
*/
|
||||
function setMinter(address _minter, bool _isActive) external onlyOwner {
|
||||
if (_minter == address(0)) revert InvalidMinter();
|
||||
isMinter[_minter] = _isActive;
|
||||
emit MinterSet(_minter, _isActive);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 铸造ytLP代币
|
||||
* @param _to 接收地址
|
||||
* @param _amount 铸造数量
|
||||
*/
|
||||
function mint(address _to, uint256 _amount) external onlyMinter {
|
||||
_mint(_to, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 销毁ytLP代币
|
||||
* @param _from 销毁地址
|
||||
* @param _amount 销毁数量
|
||||
*/
|
||||
function burn(address _from, uint256 _amount) external onlyMinter {
|
||||
_burn(_from, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dev 预留存储空间,用于未来升级时添加新的状态变量
|
||||
* 50个slot = 50 * 32 bytes = 1600 bytes
|
||||
*/
|
||||
uint256[50] private __gap;
|
||||
}
|
||||
|
||||
161
contracts/ytLp/tokens/YTToken.sol
Normal file
161
contracts/ytLp/tokens/YTToken.sol
Normal file
@@ -0,0 +1,161 @@
|
||||
// SPDX-License-Identifier: MIT
|
||||
pragma solidity ^0.8.0;
|
||||
|
||||
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
|
||||
import "@openzeppelin/contracts/access/Ownable.sol";
|
||||
|
||||
/**
|
||||
* @title YTToken
|
||||
* @notice YT代币示例实现(Yield Token)
|
||||
* @dev 展示如何实现价格接口供YTPriceFeed读取
|
||||
*/
|
||||
contract YTToken is ERC20, Ownable {
|
||||
|
||||
error NotUpdater();
|
||||
error InvalidUpdater();
|
||||
error IntervalTooLong();
|
||||
error UpdateTooFrequent();
|
||||
error InvalidYield();
|
||||
error InvalidAmount();
|
||||
error InsufficientAssets();
|
||||
|
||||
uint256 public constant PRICE_PRECISION = 10 ** 30;
|
||||
|
||||
uint256 public totalAssets;
|
||||
uint256 public accumulatedYield;
|
||||
|
||||
// 价格变量
|
||||
uint256 public assetPrice;
|
||||
uint256 public lastPriceUpdate;
|
||||
|
||||
// 价格更新控制
|
||||
address public priceUpdater;
|
||||
uint256 public minUpdateInterval = 5 minutes; // 最小更新间隔
|
||||
|
||||
event PriceUpdated(uint256 oldPrice, uint256 newPrice, uint256 timestamp);
|
||||
event YieldAccumulated(uint256 amount, uint256 timestamp);
|
||||
event PriceUpdaterSet(address indexed updater);
|
||||
event MinUpdateIntervalSet(uint256 interval);
|
||||
|
||||
modifier onlyPriceUpdater() {
|
||||
if (msg.sender != priceUpdater && msg.sender != owner()) revert NotUpdater();
|
||||
_;
|
||||
}
|
||||
|
||||
constructor(
|
||||
string memory name,
|
||||
string memory symbol,
|
||||
address _priceUpdater
|
||||
) ERC20(name, symbol) Ownable(msg.sender) {
|
||||
assetPrice = PRICE_PRECISION; // 初始价格为1
|
||||
lastPriceUpdate = block.timestamp;
|
||||
priceUpdater = _priceUpdater;
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置价格更新者
|
||||
*/
|
||||
function setPriceUpdater(address _updater) external onlyOwner {
|
||||
if (_updater == address(0)) revert InvalidUpdater();
|
||||
priceUpdater = _updater;
|
||||
emit PriceUpdaterSet(_updater);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 设置最小更新间隔
|
||||
*/
|
||||
function setMinUpdateInterval(uint256 _interval) external onlyOwner {
|
||||
if (_interval > 1 hours) revert IntervalTooLong();
|
||||
minUpdateInterval = _interval;
|
||||
emit MinUpdateIntervalSet(_interval);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 更新代币价格
|
||||
* @dev 只能由授权的updater调用,有最小时间间隔限制
|
||||
*/
|
||||
function updatePrice() public onlyPriceUpdater {
|
||||
if (block.timestamp < lastPriceUpdate + minUpdateInterval) revert UpdateTooFrequent();
|
||||
|
||||
uint256 oldPrice = assetPrice;
|
||||
uint256 supply = totalSupply();
|
||||
|
||||
if (supply == 0) {
|
||||
assetPrice = PRICE_PRECISION;
|
||||
} else {
|
||||
uint256 totalValue = totalAssets + accumulatedYield;
|
||||
// 计算每个token对应的USDC价值(18位精度)
|
||||
uint256 usdcPerToken = totalValue * 1e18 / supply;
|
||||
// 转换为30位精度的价格
|
||||
assetPrice = usdcPerToken * PRICE_PRECISION / 1e18;
|
||||
}
|
||||
|
||||
lastPriceUpdate = block.timestamp;
|
||||
|
||||
emit PriceUpdated(oldPrice, assetPrice, block.timestamp);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 累积收益并更新价格
|
||||
* @dev 当从收益策略中收到新收益时调用
|
||||
*/
|
||||
function updateYield(uint256 _newYield) external onlyPriceUpdater {
|
||||
if (_newYield == 0) revert InvalidYield();
|
||||
|
||||
accumulatedYield += _newYield;
|
||||
|
||||
emit YieldAccumulated(_newYield, block.timestamp);
|
||||
|
||||
// 收益更新后立即更新价格
|
||||
if (block.timestamp >= lastPriceUpdate + minUpdateInterval) {
|
||||
uint256 oldPrice = assetPrice;
|
||||
uint256 supply = totalSupply();
|
||||
|
||||
if (supply > 0) {
|
||||
uint256 totalValue = totalAssets + accumulatedYield;
|
||||
uint256 usdcPerToken = totalValue * 1e18 / supply;
|
||||
assetPrice = usdcPerToken * PRICE_PRECISION / 1e18;
|
||||
}
|
||||
|
||||
lastPriceUpdate = block.timestamp;
|
||||
emit PriceUpdated(oldPrice, assetPrice, block.timestamp);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 存入资产(模拟)
|
||||
* @dev 实际实现中应该处理真实的USDC存款
|
||||
*/
|
||||
function deposit(uint256 _amount) external onlyOwner {
|
||||
if (_amount == 0) revert InvalidAmount();
|
||||
totalAssets += _amount;
|
||||
_mint(msg.sender, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 提取资产(模拟)
|
||||
* @dev 实际实现中应该处理真实的USDC提款
|
||||
*/
|
||||
function withdraw(uint256 _amount) external onlyOwner {
|
||||
if (_amount == 0) revert InvalidAmount();
|
||||
if (totalAssets < _amount) revert InsufficientAssets();
|
||||
totalAssets -= _amount;
|
||||
_burn(msg.sender, _amount);
|
||||
}
|
||||
|
||||
/**
|
||||
* @notice 获取当前价格信息
|
||||
*/
|
||||
function getPriceInfo() external view returns (
|
||||
uint256 price,
|
||||
uint256 lastUpdate,
|
||||
uint256 timeSinceUpdate,
|
||||
uint256 totalVal
|
||||
) {
|
||||
price = assetPrice;
|
||||
lastUpdate = lastPriceUpdate;
|
||||
timeSinceUpdate = block.timestamp - lastPriceUpdate;
|
||||
totalVal = totalAssets + accumulatedYield;
|
||||
}
|
||||
}
|
||||
|
||||
53
deployments-vault-system.json
Normal file
53
deployments-vault-system.json
Normal file
@@ -0,0 +1,53 @@
|
||||
{
|
||||
"network": "arbSepolia",
|
||||
"chainId": "421614",
|
||||
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
|
||||
"timestamp": "2025-12-18T03:48:32.768Z",
|
||||
"wusdAddress": "0x6d2bf81a631dFE19B2f348aE92cF6Ef41ca2DF98",
|
||||
"defaultHardCap": "10000000000000000000000000",
|
||||
"contracts": {
|
||||
"YTAssetVault": {
|
||||
"implementation": "0x5f0BB22F72BFc2F0903038c46E03d49E254EBCD4"
|
||||
},
|
||||
"YTAssetFactory": {
|
||||
"proxy": "0x982716f32F10BCB5B5944c1473a8992354bF632b",
|
||||
"implementation": "0x310755c2a15f03bf94689B0A730BbFa82A20fce4"
|
||||
}
|
||||
},
|
||||
"vaults": [
|
||||
{
|
||||
"name": "YT Token A",
|
||||
"symbol": "YT-A",
|
||||
"address": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748",
|
||||
"index": "0",
|
||||
"manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
|
||||
"hardCap": "10000000000000000000000000",
|
||||
"redemptionTime": 1797565718,
|
||||
"wusdPrice": "1000000000000000000000000000000",
|
||||
"ytPrice": "1000000000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"name": "YT Token B",
|
||||
"symbol": "YT-B",
|
||||
"address": "0x719D16769757b7E87a89A3B3e0Cc259c5705135c",
|
||||
"index": "1",
|
||||
"manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
|
||||
"hardCap": "10000000000000000000000000",
|
||||
"redemptionTime": 1797565718,
|
||||
"wusdPrice": "1000000000000000000000000000000",
|
||||
"ytPrice": "1000000000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"name": "YT Token C",
|
||||
"symbol": "YT-C",
|
||||
"address": "0xcB45C64c2314Ed6EBe916C7F71D575AebA19c8Ce",
|
||||
"index": "2",
|
||||
"manager": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
|
||||
"hardCap": "10000000000000000000000000",
|
||||
"redemptionTime": 1797565718,
|
||||
"wusdPrice": "1000000000000000000000000000000",
|
||||
"ytPrice": "1000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"lastUpdate": "2025-12-18T03:48:52.103Z"
|
||||
}
|
||||
32
deployments-whitelist-config.json
Normal file
32
deployments-whitelist-config.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"timestamp": "2025-12-18T03:50:23.682Z",
|
||||
"operator": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
|
||||
"whitelistedVaults": [
|
||||
{
|
||||
"name": "YT Token A",
|
||||
"symbol": "YT-A",
|
||||
"address": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748",
|
||||
"weight": 4000,
|
||||
"maxUsdyAmount": "45000000000000000000000000",
|
||||
"price": "1000000000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"name": "YT Token B",
|
||||
"symbol": "YT-B",
|
||||
"address": "0x719D16769757b7E87a89A3B3e0Cc259c5705135c",
|
||||
"weight": 3000,
|
||||
"maxUsdyAmount": "35000000000000000000000000",
|
||||
"price": "1000000000000000000000000000000"
|
||||
},
|
||||
{
|
||||
"name": "YT Token C",
|
||||
"symbol": "YT-C",
|
||||
"address": "0xcB45C64c2314Ed6EBe916C7F71D575AebA19c8Ce",
|
||||
"weight": 2000,
|
||||
"maxUsdyAmount": "25000000000000000000000000",
|
||||
"price": "1000000000000000000000000000000"
|
||||
}
|
||||
],
|
||||
"totalWeight": "9000",
|
||||
"wusdPriceSource": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748"
|
||||
}
|
||||
15
deployments-wusd.json
Normal file
15
deployments-wusd.json
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
"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
|
||||
}
|
||||
}
|
||||
}
|
||||
33
deployments-ytlp-config.json
Normal file
33
deployments-ytlp-config.json
Normal file
@@ -0,0 +1,33 @@
|
||||
{
|
||||
"network": "arbSepolia",
|
||||
"chainId": "421614",
|
||||
"configurer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
|
||||
"timestamp": "2025-12-18T03:49:43.544Z",
|
||||
"configuration": {
|
||||
"permissions": {
|
||||
"usdyVaults": [
|
||||
"0xbC2e4f06601B92B3F430962a8f0a7E8c378ce54e",
|
||||
"0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6"
|
||||
],
|
||||
"ytlpMinters": [
|
||||
"0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6"
|
||||
],
|
||||
"vaultPoolManager": "0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6",
|
||||
"vaultSwappers": [
|
||||
"0x953758c02ec49F1f67fE2a8E3F67C434FeC5aB9d"
|
||||
],
|
||||
"poolManagerHandlers": [
|
||||
"0x953758c02ec49F1f67fE2a8E3F67C434FeC5aB9d"
|
||||
],
|
||||
"priceFeedKeepers": [
|
||||
"0xa013422A5918CD099C63c8CC35283EACa99a705d"
|
||||
],
|
||||
"priceFeedWusdSource": "0x5A12b925B8a189C5b9c269388eA62cD0014f1748"
|
||||
},
|
||||
"parameters": {
|
||||
"dynamicFees": true,
|
||||
"maxSwapSlippageBps": 1000,
|
||||
"maxPriceChangeBps": 500
|
||||
}
|
||||
}
|
||||
}
|
||||
32
deployments-ytlp.json
Normal file
32
deployments-ytlp.json
Normal file
@@ -0,0 +1,32 @@
|
||||
{
|
||||
"network": "arbSepolia",
|
||||
"chainId": "421614",
|
||||
"deployer": "0xa013422A5918CD099C63c8CC35283EACa99a705d",
|
||||
"timestamp": "2025-12-18T03:48:03.817Z",
|
||||
"contracts": {
|
||||
"USDY": {
|
||||
"proxy": "0x54551451E14D3d3418e4Aa9F31e9E8573fd37053",
|
||||
"implementation": "0xb14d186d4EAcE8131a449126c6208165a3F5FC5b"
|
||||
},
|
||||
"YTLPToken": {
|
||||
"proxy": "0xf5206D958f692556603806A8f65bB106E23d1776",
|
||||
"implementation": "0x0C3fa01b2D0596B4190edEF1B77534237231C77e"
|
||||
},
|
||||
"YTPriceFeed": {
|
||||
"proxy": "0x9364D3aF669886883C26EC0ff32000719491452A",
|
||||
"implementation": "0x83bdD4dc68AE608AEDE0f232e2d826b09B19004f"
|
||||
},
|
||||
"YTVault": {
|
||||
"proxy": "0xbC2e4f06601B92B3F430962a8f0a7E8c378ce54e",
|
||||
"implementation": "0x61278a2EBFC07eF0F7f84407291aAD07DA596AB2"
|
||||
},
|
||||
"YTPoolManager": {
|
||||
"proxy": "0xe3068a25D6eEda551Cd12CC291813A4fe0e4AbB6",
|
||||
"implementation": "0x96Fe19188c3c7d0EDA441dafC7976fBB3526d28c"
|
||||
},
|
||||
"YTRewardRouter": {
|
||||
"proxy": "0x953758c02ec49F1f67fE2a8E3F67C434FeC5aB9d",
|
||||
"implementation": "0x7A322e130fb10C3d3e2297A6C362E0d36459F1B0"
|
||||
}
|
||||
}
|
||||
}
|
||||
1954
doc/YT-LiquidityPool设计方案.md
Normal file
1954
doc/YT-LiquidityPool设计方案.md
Normal file
File diff suppressed because it is too large
Load Diff
374
doc/YTLending-流程说明.md
Normal file
374
doc/YTLending-流程说明.md
Normal file
@@ -0,0 +1,374 @@
|
||||
# YT Lending 借贷池系统流程说明
|
||||
|
||||
## 系统概述
|
||||
|
||||
YT Lending 是基于 Compound V3 架构的简化借贷池系统,采用 OpenZeppelin UUPS 升级模式和 Ownable 权限管理。
|
||||
|
||||
### 核心特性
|
||||
|
||||
- ✅ **UUPS 可升级**:使用 OpenZeppelin 的 UUPS 代理模式
|
||||
- ✅ **简化权限**:使用 Owner 权限管理,替代复杂的 Governor 治理
|
||||
- ✅ **单一基础资产**:支持一种基础资产(如 USDC)的借贷
|
||||
- ✅ **多种抵押品**:支持多种抵押资产(如 ETH、WBTC)
|
||||
- ✅ **动态利率**:双拐点利率模型
|
||||
- ✅ **清算机制**:支持不良贷款清算和抵押品拍卖
|
||||
|
||||
---
|
||||
|
||||
## 合约架构
|
||||
|
||||
```
|
||||
├── Lending.sol # 核心借贷合约(UUPS)
|
||||
├── LendingFactory.sol # 工厂合约
|
||||
├── Configurator.sol # 配置管理合约(UUPS)
|
||||
├── LendingConfiguration.sol # 配置结构体
|
||||
├── LendingStorage.sol # 存储定义
|
||||
├── LendingMath.sol # 数学计算库
|
||||
├── ConfiguratorStorage.sol # 配置器存储
|
||||
└── interfaces/
|
||||
├── ILending.sol # 借贷接口
|
||||
└── IPriceFeed.sol # 价格预言机接口
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 部署流程
|
||||
|
||||
### 步骤 1: 部署基础合约
|
||||
|
||||
运行部署脚本:
|
||||
```bash
|
||||
npx hardhat run scripts/deploy/07-deployLending.ts --network <network>
|
||||
```
|
||||
|
||||
部署内容:
|
||||
1. **LendingFactory** - 工厂合约
|
||||
2. **Configurator Implementation** - 配置管理实现合约
|
||||
3. **Configurator Proxy** - 配置管理代理合约
|
||||
4. **Lending Implementation** - 借贷池实现合约
|
||||
|
||||
### 步骤 2: 配置市场参数
|
||||
|
||||
运行配置脚本:
|
||||
```bash
|
||||
npx hardhat run scripts/deploy/08-configureLending.ts --network <network>
|
||||
```
|
||||
|
||||
配置内容:
|
||||
1. 设置工厂合约地址
|
||||
2. 配置市场参数(利率模型、清算参数等)
|
||||
3. 添加抵押资产配置
|
||||
4. 部署 Lending Proxy 代理合约
|
||||
|
||||
---
|
||||
|
||||
## 配置参数说明
|
||||
|
||||
### 利率模型参数
|
||||
|
||||
| 参数 | 说明 | 示例值 |
|
||||
|------|------|--------|
|
||||
| `supplyKink` | 供应利率拐点(利用率) | 80% |
|
||||
| `supplyPerYearInterestRateSlopeLow` | 供应拐点前斜率 | 3% APY |
|
||||
| `supplyPerYearInterestRateSlopeHigh` | 供应拐点后斜率 | 40% APY |
|
||||
| `borrowKink` | 借款利率拐点(利用率) | 80% |
|
||||
| `borrowPerYearInterestRateSlopeLow` | 借款拐点前斜率 | 5% APY |
|
||||
| `borrowPerYearInterestRateSlopeHigh` | 借款拐点后斜率 | 150% APY |
|
||||
|
||||
### 抵押资产参数
|
||||
|
||||
| 参数 | 说明 | 示例值 |
|
||||
|------|------|--------|
|
||||
| `borrowCollateralFactor` | 借款抵押率(LTV) | 80% |
|
||||
| `liquidateCollateralFactor` | 清算抵押率 | 85% |
|
||||
| `liquidationFactor` | 清算激励 | 5% |
|
||||
| `supplyCap` | 供应上限 | 100,000 ETH |
|
||||
|
||||
---
|
||||
|
||||
## 核心功能流程
|
||||
|
||||
### 1. 存款(Supply)
|
||||
|
||||
```solidity
|
||||
lending.supply(1000 * 1e6); // 存入 1000 USDC
|
||||
```
|
||||
|
||||
**流程**:
|
||||
1. 用户授权 USDC 给 Lending 合约
|
||||
2. 调用 `supply()` 存入 USDC
|
||||
3. 合约记录用户正余额
|
||||
4. 开始计息
|
||||
|
||||
### 2. 存入抵押品(Supply Collateral)
|
||||
|
||||
```solidity
|
||||
lending.supplyCollateral(WETH, 10 * 1e18); // 存入 10 ETH
|
||||
```
|
||||
|
||||
**流程**:
|
||||
1. 用户授权抵押品(如 WETH)给 Lending 合约
|
||||
2. 调用 `supplyCollateral()` 存入抵押品
|
||||
3. 合约记录用户抵押品余额
|
||||
|
||||
### 3. 借款(Borrow)
|
||||
|
||||
```solidity
|
||||
lending.borrow(5000 * 1e6); // 借出 5000 USDC
|
||||
```
|
||||
|
||||
**流程**:
|
||||
1. 用户已存入足够的抵押品
|
||||
2. 调用 `borrow()` 借出 USDC
|
||||
3. 合约检查抵押品是否充足(根据 borrowCollateralFactor)
|
||||
4. 用户余额变为负数(表示借款)
|
||||
5. 开始计息
|
||||
|
||||
**借款能力计算**:
|
||||
```
|
||||
借款能力 = Σ(抵押品价值 × borrowCollateralFactor)
|
||||
```
|
||||
|
||||
### 4. 取出资产(Withdraw)
|
||||
|
||||
```solidity
|
||||
lending.withdraw(500 * 1e6); // 取出 500 USDC
|
||||
```
|
||||
|
||||
**流程**:
|
||||
1. 调用 `withdraw()` 取出 USDC
|
||||
2. 如果用户有借款,检查抵押品是否充足
|
||||
3. 转账 USDC 给用户
|
||||
|
||||
### 5. 取出抵押品(Withdraw Collateral)
|
||||
|
||||
```solidity
|
||||
lending.withdrawCollateral(WETH, 2 * 1e18); // 取出 2 ETH
|
||||
```
|
||||
|
||||
**流程**:
|
||||
1. 调用 `withdrawCollateral()` 取出抵押品
|
||||
2. 如果用户有借款,检查剩余抵押品是否充足
|
||||
3. 转账抵押品给用户
|
||||
|
||||
### 6. 清算(Absorb)
|
||||
|
||||
```solidity
|
||||
lending.absorb(borrowerAddress); // 清算借款人
|
||||
```
|
||||
|
||||
**触发条件**:
|
||||
```
|
||||
债务 > Σ(抵押品价值 × liquidateCollateralFactor)
|
||||
```
|
||||
|
||||
**流程**:
|
||||
1. 清算人调用 `absorb()` 清算不良贷款
|
||||
2. 合约检查借款人是否可被清算
|
||||
3. 将借款人的债务清零
|
||||
4. 将借款人的抵押品转移到清算库存
|
||||
|
||||
### 7. 购买清算抵押品(Buy Collateral)
|
||||
|
||||
```solidity
|
||||
lending.buyCollateral(WETH, 1 * 1e18, 2000 * 1e6);
|
||||
// 用 2000 USDC 购买至少 1 ETH
|
||||
```
|
||||
|
||||
**流程**:
|
||||
1. 购买者调用 `buyCollateral()`
|
||||
2. 按折扣价(storeFrontPriceFactor)计算可购买的抵押品数量
|
||||
3. 转账 USDC 给合约
|
||||
4. 转账抵押品给购买者
|
||||
|
||||
**折扣价格计算**:
|
||||
```
|
||||
折扣价 = 市场价 × storeFrontPriceFactor
|
||||
可购买数量 = 支付 USDC 数量 / 折扣价
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 利率计算
|
||||
|
||||
### 利用率
|
||||
|
||||
```
|
||||
利用率 = 总借款 / 总供应
|
||||
```
|
||||
|
||||
### 双拐点利率模型
|
||||
|
||||
```
|
||||
如果 利用率 <= Kink:
|
||||
利率 = 基础利率 + 利用率 × 低斜率
|
||||
|
||||
如果 利用率 > Kink:
|
||||
超额利用率 = 利用率 - Kink
|
||||
利率 = 基础利率 + 低斜率 + 超额利用率 × 高斜率
|
||||
```
|
||||
|
||||
**示例**(借款利率,Kink = 80%):
|
||||
|
||||
| 利用率 | 借款利率 |
|
||||
|--------|----------|
|
||||
| 0% | 1.5% |
|
||||
| 40% | 3.5% |
|
||||
| 80% | 5.5% |
|
||||
| 90% | 20.5% |
|
||||
| 100% | 35.5% |
|
||||
|
||||
### 利率计算优化(采用 Compound V3 方式)
|
||||
|
||||
**关键优化**:配置时传入年化利率,初始化时自动转换为每秒利率
|
||||
|
||||
```solidity
|
||||
// 初始化时(只计算一次)
|
||||
uint256 SECONDS_PER_YEAR = 31,536,000;
|
||||
supplyPerSecondRate = supplyPerYearRate / SECONDS_PER_YEAR;
|
||||
borrowPerSecondRate = borrowPerYearRate / SECONDS_PER_YEAR;
|
||||
|
||||
// 每次计提利息(高效计算)
|
||||
newIndex = oldIndex + (oldIndex * perSecondRate * timeElapsed) / 1e18;
|
||||
```
|
||||
|
||||
**优化效果**:
|
||||
- ✅ 精度更高:每秒利率避免了重复除法导致的精度损失
|
||||
- ✅ Gas 更低:每次计提节省 ~100 gas(~66% Gas 优化)
|
||||
- ✅ 计算更快:只需乘法,无需除以 31,536,000
|
||||
- ✅ 完全兼容:配置文件仍使用易读的年化利率
|
||||
|
||||
---
|
||||
|
||||
## 权限管理
|
||||
|
||||
### Owner 权限
|
||||
|
||||
Owner(所有者)可以执行以下操作:
|
||||
|
||||
1. **升级合约**:调用 `upgradeTo()` 升级 Lending 或 Configurator
|
||||
2. **暂停/恢复**:调用 `pause()` / `unpause()` 暂停或恢复合约
|
||||
3. **配置市场**:通过 Configurator 修改市场参数
|
||||
4. **转移所有权**:调用 `transferOwnership()` 转移 Owner
|
||||
|
||||
### 推荐配置
|
||||
|
||||
建议使用多签钱包(如 Gnosis Safe)作为 Owner:
|
||||
|
||||
```typescript
|
||||
// 部署后转移所有权到多签
|
||||
await lending.transferOwnership(GNOSIS_SAFE_ADDRESS);
|
||||
await configurator.transferOwnership(GNOSIS_SAFE_ADDRESS);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 安全注意事项
|
||||
|
||||
### ⚠️ 关键风险
|
||||
|
||||
1. **价格预言机风险**:依赖外部价格源,需确保价格源可靠
|
||||
2. **清算延迟风险**:市场剧烈波动时可能来不及清算
|
||||
3. **Owner 权限过大**:Owner 拥有所有管理权限,需使用多签
|
||||
|
||||
### 🔒 安全建议
|
||||
|
||||
1. **使用多签钱包**:将 Owner 设为 Gnosis Safe 等多签钱包
|
||||
2. **设置合理参数**:
|
||||
- `borrowCollateralFactor` < `liquidateCollateralFactor`
|
||||
- 合理的清算折扣(storeFrontPriceFactor)
|
||||
- 适当的 supplyCap 防止单一资产风险过大
|
||||
3. **监控系统**:实时监控抵押率,及时清算
|
||||
4. **价格源多样化**:考虑使用多个价格源取平均
|
||||
|
||||
---
|
||||
|
||||
## 升级流程
|
||||
|
||||
### 使用 upgrades 插件升级(推荐)
|
||||
|
||||
运行升级脚本:
|
||||
```bash
|
||||
npx hardhat run scripts/deploy/09-upgradeLending.ts --network <network>
|
||||
```
|
||||
|
||||
**脚本特性**:
|
||||
- ✅ 自动验证存储布局兼容性
|
||||
- ✅ 自动部署新实现合约
|
||||
- ✅ 自动更新代理指向
|
||||
- ✅ 保留所有状态数据
|
||||
|
||||
**修改升级目标**:
|
||||
```typescript
|
||||
// 在 09-upgradeLending.ts 中修改
|
||||
const UPGRADE_LENDING = true; // true = 升级 Lending, false = 升级 Configurator
|
||||
```
|
||||
|
||||
### 手动 UUPS 升级步骤(不推荐)
|
||||
|
||||
如果需要手动升级:
|
||||
|
||||
1. **部署新实现合约**:
|
||||
```typescript
|
||||
const NewLending = await ethers.getContractFactory("LendingV2");
|
||||
const newImpl = await NewLending.deploy();
|
||||
```
|
||||
|
||||
2. **升级代理**:
|
||||
```typescript
|
||||
await lending.upgradeTo(newImpl.address);
|
||||
```
|
||||
|
||||
### 注意事项
|
||||
|
||||
- ✅ 只有 Owner 可以升级
|
||||
- ✅ 必须保持存储布局一致
|
||||
- ✅ 只能在末尾添加新存储变量
|
||||
- ⚠️ 升级前在测试网充分测试
|
||||
- 🔧 推荐使用 upgrades 插件,它会自动验证兼容性
|
||||
|
||||
---
|
||||
|
||||
## 监控指标
|
||||
|
||||
### 关键指标
|
||||
|
||||
1. **利用率**:`totalBorrow / totalSupply`
|
||||
2. **供应利率**:`getSupplyRate()`
|
||||
3. **借款利率**:`getBorrowRate()`
|
||||
4. **储备金**:`reserves`
|
||||
5. **清算库存**:`collateralReserves[asset]`
|
||||
|
||||
### 健康检查
|
||||
|
||||
```typescript
|
||||
// 检查利用率
|
||||
const utilization = totalBorrow.mul(1e18).div(totalSupply);
|
||||
console.log("Utilization:", utilization / 1e18 * 100, "%");
|
||||
|
||||
// 检查是否需要清算
|
||||
const isLiquidatable = await lending.isLiquidatable(userAddress);
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 总结
|
||||
|
||||
YT Lending 提供了一个简化但功能完整的借贷池系统:
|
||||
|
||||
- ✅ 核心借贷功能(存款、借款、抵押品管理)
|
||||
- ✅ 清算机制(absorb + buyCollateral)
|
||||
- ✅ 动态利率模型(双拐点)
|
||||
- ✅ 可升级架构(UUPS)
|
||||
- ✅ 简化权限管理(Owner)
|
||||
|
||||
**适用场景**:
|
||||
- 中小型借贷协议
|
||||
- 需要快速上线的项目
|
||||
- 中心化或半中心化管理的借贷池
|
||||
|
||||
**限制**:
|
||||
- 单一基础资产(只能借贷一种资产)
|
||||
- 简化的权限模型(不支持 DAO 治理)
|
||||
- 需要可靠的价格预言机
|
||||
|
||||
1151
doc/YTLp-系统操作流程图.md
Normal file
1151
doc/YTLp-系统操作流程图.md
Normal file
File diff suppressed because it is too large
Load Diff
1554
doc/YT资产金库系统操作流程图.md
Normal file
1554
doc/YT资产金库系统操作流程图.md
Normal file
File diff suppressed because it is too large
Load Diff
10
env.example
Normal file
10
env.example
Normal file
@@ -0,0 +1,10 @@
|
||||
# Network Configuration
|
||||
SEPOLIA_RPC_URL=https://sepolia.infura.io/v3/YOUR_INFURA_KEY
|
||||
SEPOLIA_PRIVATE_KEY=your_private_key_here
|
||||
|
||||
# Etherscan API Key (for contract verification)
|
||||
ETHERSCAN_API_KEY=your_etherscan_api_key
|
||||
|
||||
# Optional
|
||||
MAINNET_RPC_URL=
|
||||
COINMARKETCAP_API_KEY=
|
||||
9
foundry.toml
Normal file
9
foundry.toml
Normal file
@@ -0,0 +1,9 @@
|
||||
[profile.default]
|
||||
src = 'contracts'
|
||||
out = 'out'
|
||||
libs = ['node_modules', 'lib']
|
||||
test = 'test'
|
||||
cache_path = 'cache_forge'
|
||||
via_ir = true
|
||||
optimizer = true
|
||||
optimizer_runs = 200
|
||||
282
hardhat.config.ts
Normal file
282
hardhat.config.ts
Normal file
@@ -0,0 +1,282 @@
|
||||
import "@nomicfoundation/hardhat-foundry";
|
||||
import type { HardhatUserConfig } from "hardhat/config";
|
||||
import "@nomicfoundation/hardhat-toolbox";
|
||||
import "@matterlabs/hardhat-zksync-deploy";
|
||||
import "@matterlabs/hardhat-zksync-solc";
|
||||
import "hardhat-abi-exporter";
|
||||
import * as dotenv from "dotenv";
|
||||
dotenv.config();
|
||||
import "hardhat-contract-sizer";
|
||||
import "hardhat-gas-reporter";
|
||||
import "@openZeppelin/hardhat-upgrades";
|
||||
import "@typechain/hardhat";
|
||||
|
||||
const accounts =
|
||||
process.env.PRIVATE_KEY !== undefined ? [process.env.PRIVATE_KEY] : [];
|
||||
|
||||
const config: HardhatUserConfig = {
|
||||
// 编译配置
|
||||
solidity: {
|
||||
version: "0.8.28",
|
||||
settings: {
|
||||
optimizer: {
|
||||
enabled: true,
|
||||
runs: 200,
|
||||
},
|
||||
viaIR: true,
|
||||
outputSelection: {
|
||||
'*': {
|
||||
'*': [
|
||||
'abi',
|
||||
'evm.bytecode',
|
||||
'evm.deployedBytecode',
|
||||
'evm.methodIdentifiers',
|
||||
'metadata',
|
||||
'storageLayout' // 用于升级验证
|
||||
],
|
||||
'': ['ast'] // 源代码 AST
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
zksolc: {
|
||||
version: "1.3.22",
|
||||
compilerSource: "binary",
|
||||
settings: {
|
||||
isSystem: false, // optional. Enables Yul instructions available only for zkSync system contracts and libraries
|
||||
forceEvmla: false, // optional. Falls back to EVM legacy assembly if there is a bug with Yul
|
||||
optimizer: {
|
||||
enabled: true, // optional. True by default
|
||||
mode: 'z' // optional. 3 by default, z to optimize bytecode size
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
// 设置单个测试用例的最大执行时间
|
||||
mocha: {
|
||||
timeout: 10 * 60 * 1000,
|
||||
},
|
||||
|
||||
// 网络配置
|
||||
networks: {
|
||||
hardhat: {
|
||||
allowUnlimitedContractSize: false,
|
||||
chainId: 1,
|
||||
},
|
||||
localhost:{
|
||||
url:"http://127.0.0.1:8545",
|
||||
accounts:accounts,
|
||||
},
|
||||
eth: {
|
||||
url: "https://ethereum-rpc.publicnode.com",
|
||||
accounts: accounts,
|
||||
chainId: 1,
|
||||
},
|
||||
op: {
|
||||
url: "https://optimism-rpc.publicnode.com",
|
||||
accounts: accounts,
|
||||
chainId: 10,
|
||||
},
|
||||
bsc: {
|
||||
url:"https://bsc.drpc.org",
|
||||
accounts: accounts,
|
||||
chainId: 56,
|
||||
},
|
||||
wld: {
|
||||
url: "https://480.rpc.thirdweb.com",
|
||||
accounts: accounts,
|
||||
chainId: 480,
|
||||
},
|
||||
polygon: {
|
||||
url:"https://polygon.drpc.org",
|
||||
accounts: accounts,
|
||||
chainId: 137,
|
||||
},
|
||||
ftm: {
|
||||
url: "https://fantom-json-rpc.stakely.io",
|
||||
accounts: accounts,
|
||||
chainId: 250,
|
||||
},
|
||||
zk: {
|
||||
url: "https://mainnet.era.zksync.io",
|
||||
accounts: accounts,
|
||||
ethNetwork: "mainnet",
|
||||
zksync: true,
|
||||
chainId: 324,
|
||||
},
|
||||
linea: {
|
||||
url: "https://linea.drpc.org",
|
||||
accounts: accounts,
|
||||
chainId: 59144,
|
||||
},
|
||||
base: {
|
||||
url: "https://base.drpc.org",
|
||||
accounts: accounts,
|
||||
chainId: 8453,
|
||||
},
|
||||
arb: {
|
||||
url: "https://public-arb-mainnet.fastnode.io",
|
||||
accounts: accounts,
|
||||
chainId: 42161,
|
||||
},
|
||||
blast: {
|
||||
url: "https://blast.drpc.org",
|
||||
accounts: accounts,
|
||||
chainId: 81457,
|
||||
},
|
||||
avax: {
|
||||
url:"https://endpoints.omniatech.io/v1/avax/mainnet/public",
|
||||
accounts: accounts,
|
||||
chainId: 43114,
|
||||
},
|
||||
gateLayer: {
|
||||
url: "https://gatelayer-mainnet.gatenode.cc",
|
||||
accounts: accounts,
|
||||
chainId: 10088,
|
||||
},
|
||||
baseSepolia: {
|
||||
url: "https://base-sepolia.drpc.org",
|
||||
accounts: accounts,
|
||||
chainId: 84532,
|
||||
},
|
||||
arbSepolia: {
|
||||
url: "https://arbitrum-sepolia.gateway.tenderly.co",
|
||||
accounts: accounts,
|
||||
chainId: 421614,
|
||||
},
|
||||
},
|
||||
|
||||
// gas报告配置
|
||||
gasReporter: {
|
||||
currency: "USDT",
|
||||
enabled: !!process.env.REPORT_GAS,
|
||||
},
|
||||
|
||||
// 合约大小报告配置
|
||||
contractSizer: {
|
||||
alphaSort: true,
|
||||
disambiguatePaths: false,
|
||||
runOnCompile: true,
|
||||
strict: false,
|
||||
only: [],
|
||||
},
|
||||
|
||||
// ABI导出配置
|
||||
abiExporter: {
|
||||
path: "./abis",
|
||||
runOnCompile: true,
|
||||
clear: true,
|
||||
flat: true,
|
||||
pretty: false,
|
||||
except: ["lib"],
|
||||
},
|
||||
|
||||
// 合约验证配置 (Etherscan V2 API)
|
||||
etherscan: {
|
||||
apiKey: process.env.ETHERSCAN_API_KEY as string,
|
||||
customChains: [
|
||||
{
|
||||
network: "arbSepolia",
|
||||
chainId: 421614,
|
||||
urls: {
|
||||
apiURL: "https://api-sepolia.arbiscan.io/api",
|
||||
browserURL: "https://sepolia.arbiscan.io"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "arb",
|
||||
chainId: 42161,
|
||||
urls: {
|
||||
apiURL: "https://api.arbiscan.io/api",
|
||||
browserURL: "https://arbiscan.io"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "baseSepolia",
|
||||
chainId: 84532,
|
||||
urls: {
|
||||
apiURL: "https://api-sepolia.basescan.org/api",
|
||||
browserURL: "https://sepolia.basescan.org"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "base",
|
||||
chainId: 8453,
|
||||
urls: {
|
||||
apiURL: "https://api.basescan.org/api",
|
||||
browserURL: "https://basescan.org"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "op",
|
||||
chainId: 10,
|
||||
urls: {
|
||||
apiURL: "https://api-optimistic.etherscan.io/api",
|
||||
browserURL: "https://optimistic.etherscan.io"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "polygon",
|
||||
chainId: 137,
|
||||
urls: {
|
||||
apiURL: "https://api.polygonscan.com/api",
|
||||
browserURL: "https://polygonscan.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "bsc",
|
||||
chainId: 56,
|
||||
urls: {
|
||||
apiURL: "https://api.bscscan.com/api",
|
||||
browserURL: "https://bscscan.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "ftm",
|
||||
chainId: 250,
|
||||
urls: {
|
||||
apiURL: "https://api.ftmscan.com/api",
|
||||
browserURL: "https://ftmscan.com"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "avax",
|
||||
chainId: 43114,
|
||||
urls: {
|
||||
apiURL: "https://api.snowtrace.io/api",
|
||||
browserURL: "https://snowtrace.io"
|
||||
}
|
||||
},
|
||||
{
|
||||
network: "linea",
|
||||
chainId: 59144,
|
||||
urls: {
|
||||
apiURL: "https://api.lineascan.build/api",
|
||||
browserURL: "https://lineascan.build"
|
||||
}
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
// Sourcify 验证配置(可选)
|
||||
sourcify: {
|
||||
enabled: false // 设置为 true 可启用 Sourcify 验证
|
||||
},
|
||||
|
||||
// 覆盖配置
|
||||
paths: {
|
||||
sources: "./contracts",
|
||||
tests: "./test",
|
||||
cache: "./cache",
|
||||
artifacts: "./artifacts",
|
||||
},
|
||||
|
||||
// typechain配置
|
||||
typechain: {
|
||||
outDir: "typechain-types",
|
||||
target: "ethers-v6",
|
||||
},
|
||||
};
|
||||
|
||||
export default config;
|
||||
1
lib/forge-std/.gitattributes
vendored
Normal file
1
lib/forge-std/.gitattributes
vendored
Normal file
@@ -0,0 +1 @@
|
||||
src/Vm.sol linguist-generated
|
||||
1
lib/forge-std/.github/CODEOWNERS
vendored
Normal file
1
lib/forge-std/.github/CODEOWNERS
vendored
Normal file
@@ -0,0 +1 @@
|
||||
* @danipopes @klkvr @mattsse @grandizzy @yash-atreya @zerosnacks @onbjerg @0xrusowsky
|
||||
6
lib/forge-std/.github/dependabot.yml
vendored
Normal file
6
lib/forge-std/.github/dependabot.yml
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
version: 2
|
||||
updates:
|
||||
- package-ecosystem: "github-actions"
|
||||
directory: "/"
|
||||
schedule:
|
||||
interval: "weekly"
|
||||
137
lib/forge-std/.github/workflows/ci.yml
vendored
Normal file
137
lib/forge-std/.github/workflows/ci.yml
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
name: CI
|
||||
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: build +${{ matrix.toolchain }} ${{ matrix.flags }}
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
toolchain: [stable, nightly]
|
||||
flags:
|
||||
- ""
|
||||
- --via-ir
|
||||
- --use solc:0.8.17 --via-ir
|
||||
- --use solc:0.8.17
|
||||
- --use solc:0.8.0
|
||||
- --use solc:0.7.6
|
||||
- --use solc:0.7.0
|
||||
- --use solc:0.6.2
|
||||
- --use solc:0.6.12
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: foundry-rs/foundry-toolchain@v1
|
||||
- run: forge --version
|
||||
- run: |
|
||||
case "${{ matrix.flags }}" in
|
||||
*"solc:0.8.0"* | *"solc:0.7"* | *"solc:0.6"*)
|
||||
forge build --skip test --skip Config --skip StdConfig --skip LibVariable --deny-warnings ${{ matrix.flags }}
|
||||
;;
|
||||
*)
|
||||
forge build --skip test --deny-warnings ${{ matrix.flags }}
|
||||
;;
|
||||
esac
|
||||
# via-ir compilation time checks.
|
||||
- if: contains(matrix.flags, '--via-ir')
|
||||
run: forge build --skip test --deny-warnings ${{ matrix.flags }} --contracts 'test/compilation/*'
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
toolchain: [stable, nightly]
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: foundry-rs/foundry-toolchain@v1
|
||||
with:
|
||||
version: ${{ matrix.toolchain }}
|
||||
- run: forge --version
|
||||
- run: forge test -vvv
|
||||
|
||||
fmt:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: foundry-rs/foundry-toolchain@v1
|
||||
- run: forge --version
|
||||
- run: forge fmt --check
|
||||
|
||||
typos:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
contents: read
|
||||
steps:
|
||||
- uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- uses: crate-ci/typos@2d0ce569feab1f8752f1dde43cc2f2aa53236e06 # v1
|
||||
|
||||
codeql:
|
||||
name: Analyze (${{ matrix.language }})
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
security-events: write
|
||||
actions: read
|
||||
contents: read
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
include:
|
||||
- language: actions
|
||||
build-mode: none
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v4
|
||||
with:
|
||||
languages: ${{ matrix.language }}
|
||||
build-mode: ${{ matrix.build-mode }}
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v4
|
||||
with:
|
||||
category: "/language:${{matrix.language}}"
|
||||
|
||||
ci-success:
|
||||
runs-on: ubuntu-latest
|
||||
if: always()
|
||||
needs:
|
||||
- build
|
||||
- test
|
||||
- fmt
|
||||
- typos
|
||||
- codeql
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Decide whether the needed jobs succeeded or failed
|
||||
uses: re-actors/alls-green@05ac9388f0aebcb5727afa17fcccfecd6f8ec5fe # release/v1
|
||||
with:
|
||||
jobs: ${{ toJSON(needs) }}
|
||||
36
lib/forge-std/.github/workflows/sync.yml
vendored
Normal file
36
lib/forge-std/.github/workflows/sync.yml
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
name: Sync Release Branch
|
||||
|
||||
permissions: {}
|
||||
|
||||
on:
|
||||
release:
|
||||
types:
|
||||
- created
|
||||
|
||||
jobs:
|
||||
sync-release-branch:
|
||||
runs-on: ubuntu-latest
|
||||
permissions:
|
||||
contents: write
|
||||
if: startsWith(github.event.release.tag_name, 'v1')
|
||||
steps:
|
||||
- name: Check out the repo
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: true
|
||||
fetch-depth: 0
|
||||
ref: v1
|
||||
|
||||
# The email is derived from the bots user id,
|
||||
# found here: https://api.github.com/users/github-actions%5Bbot%5D
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config user.name github-actions[bot]
|
||||
git config user.email 41898282+github-actions[bot]@users.noreply.github.com
|
||||
|
||||
- name: Sync Release Branch
|
||||
run: |
|
||||
git fetch --tags
|
||||
git checkout v1
|
||||
git reset --hard ${GITHUB_REF}
|
||||
git push --force
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user