Files
Heyue_test/frontend/scripts/test-calculations.js
Sofio 5cb64f881e feat: 添加多链支持和 Lending 借贷系统
- 新增 ARB Sepolia + BNB Testnet 多链支持
- 添加 LendingPanel 借贷系统组件
- 添加 LendingAdminPanel 管理面板
- 添加 USDCPanel USDC 操作组件
- 添加 HoldersPanel 持有人信息组件
- 添加 AutoTestPanel 自动化测试组件
- 重构 LP 组件为模块化结构 (LP/)
- 添加多个调试和测试脚本
- 修复 USDC 精度动态配置
- 优化合约配置支持多链切换

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-26 23:32:29 +08:00

183 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createPublicClient, http, getAddress } from 'viem'
import { arbitrumSepolia } from 'viem/chains'
const client = createPublicClient({
chain: arbitrumSepolia,
transport: http('https://api.zan.top/node/v1/arb/sepolia/baf84c429d284bb5b676cb8c9ca21c07')
})
const LENDING_PROXY = getAddress('0xCb4E7B1069F6C26A1c27523ce4c8dfD884552d1D')
const LENDING_PRICE_FEED = getAddress('0xE82c7cB9CfA42D6eb7e443956b78f8290249c316')
const CONFIGURATOR = getAddress('0x488409CE9A3Fcd8EbD373dCb7e025cF8AB96fcdc')
const USER = getAddress('0xa013422A5918CD099C63c8CC35283EACa99a705d')
const YT_A = getAddress('0x97204190B35D9895a7a47aa7BaC61ac08De3cF05')
const LENDING_ABI = [
{
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: 'account', type: 'address' }],
name: 'borrowBalanceOf',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function'
}
]
const PRICE_FEED_ABI = [
{
inputs: [{ internalType: 'address', name: 'asset', type: 'address' }],
name: 'getPrice',
outputs: [{ internalType: 'uint256', name: '', type: 'uint256' }],
stateMutability: 'view',
type: 'function'
}
]
const CONFIGURATOR_ABI = [
{
inputs: [{ internalType: 'address', name: 'lendingProxy', type: 'address' }],
name: 'getConfiguration',
outputs: [
{
components: [
{ internalType: 'address', name: 'baseToken', type: 'address' },
{ internalType: 'address', name: 'lendingPriceSource', 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' },
{
components: [
{ internalType: 'address', name: 'asset', 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' }
],
internalType: 'struct LendingConfiguration.AssetConfig[]',
name: 'assetConfigs',
type: 'tuple[]'
}
],
internalType: 'struct LendingConfiguration.Configuration',
name: '',
type: 'tuple'
}
],
stateMutability: 'view',
type: 'function'
}
]
async function main() {
console.log('\n=== 测试抵押价值计算逻辑 ===\n')
console.log('用户:', USER)
// 1. 获取抵押品余额
console.log('\n--- 1. 获取抵押品余额 ---')
const collateral = await client.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'getCollateral',
args: [USER, YT_A]
})
console.log('YT-A 抵押品:', Number(collateral) / 1e18, 'YT-A')
console.log('原始值:', collateral.toString())
// 2. 获取价格
console.log('\n--- 2. 获取 YT-A 价格 ---')
const price = await client.readContract({
address: LENDING_PRICE_FEED,
abi: PRICE_FEED_ABI,
functionName: 'getPrice',
args: [YT_A]
})
console.log('YT-A 价格Compound V3 格式):', price.toString())
console.log(' = 1e30 规模')
// 3. 获取配置
console.log('\n--- 3. 获取配置 ---')
const config = await client.readContract({
address: CONFIGURATOR,
abi: CONFIGURATOR_ABI,
functionName: 'getConfiguration',
args: [LENDING_PROXY]
})
const ytAConfig = config.assetConfigs.find(
cfg => cfg.asset.toLowerCase() === YT_A.toLowerCase()
)
if (ytAConfig) {
console.log('YT-A 配置:')
console.log(' 借款抵押率 (borrowCollateralFactor):', ytAConfig.borrowCollateralFactor.toString())
console.log(' = ', Number(ytAConfig.borrowCollateralFactor) / 1e18 * 100, '%')
console.log(' 清算阈值 (liquidateCollateralFactor):', ytAConfig.liquidateCollateralFactor.toString())
console.log(' = ', Number(ytAConfig.liquidateCollateralFactor) / 1e18 * 100, '%')
}
// 4. 获取借款余额
console.log('\n--- 4. 获取借款余额 ---')
const borrowBalance = await client.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'borrowBalanceOf',
args: [USER]
})
console.log('借款余额:', Number(borrowBalance) / 1e6, 'USDC')
// 5. 计算总抵押价值
console.log('\n--- 5. 计算总抵押价值 ---')
// 价值USDC 6位精度= (balance * price) / 1e42
const valueInUSD = (collateral * price) / BigInt(10 ** 42)
console.log('总抵押价值:', Number(valueInUSD) / 1e6, 'USDC')
console.log('原始值 (6位精度):', valueInUSD.toString())
// 6. 计算可借额度
console.log('\n--- 6. 计算可借额度 ---')
if (ytAConfig) {
const borrowCollateralFactor = BigInt(ytAConfig.borrowCollateralFactor)
const maxBorrow = (valueInUSD * borrowCollateralFactor) / BigInt(10 ** 18)
const availableToBorrow = maxBorrow > borrowBalance ? maxBorrow - borrowBalance : 0n
console.log('最大可借:', Number(maxBorrow) / 1e6, 'USDC')
console.log('已借:', Number(borrowBalance) / 1e6, 'USDC')
console.log('剩余可借:', Number(availableToBorrow) / 1e6, 'USDC')
}
// 7. 计算健康因子
console.log('\n--- 7. 计算健康因子 ---')
if (borrowBalance > 0n && ytAConfig) {
const liquidationFactor = BigInt(ytAConfig.liquidateCollateralFactor)
const liquidationThreshold = (valueInUSD * liquidationFactor) / BigInt(10 ** 18)
// healthFactor 以 10000 为基数
const healthFactor = (liquidationThreshold * BigInt(10000)) / borrowBalance
console.log('清算阈值价值:', Number(liquidationThreshold) / 1e6, 'USDC')
console.log('健康因子 (10000=100%):', Number(healthFactor))
console.log(' = ', Number(healthFactor) / 100, '%')
} else if (borrowBalance === 0n) {
console.log('无借款,健康因子: ∞(无限大,非常安全)')
}
console.log('\n=== 计算完成 ===\n')
}
main()