Files
Heyue_test/frontend/scripts/check-lending-setup.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

238 lines
8.9 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { createPublicClient, http, parseAbi } from 'viem';
import { arbitrumSepolia } from 'viem/chains';
const LENDING_PROXY = '0xCb4E7B1069F6C26A1c27523ce4c8dfD884552d1D';
const CONFIGURATOR_ADDRESS = '0x488409CE9A3Fcd8EbD373dCb7e025cF8AB96fcdc';
const LENDING_ABI = parseAbi([
'function owner() view returns (address)',
'function configurator() view returns (address)',
'function getConfigurator() view returns (address)',
'function setConfigurator(address) external',
'function paused() view returns (bool)',
'function getTotalSupply() view returns (uint256)',
'function getTotalBorrow() view returns (uint256)',
'function getUtilization() view returns (uint256)',
'function getBorrowRate() view returns (uint256)',
'function getSupplyRate(uint256) view returns (uint256)',
'function initialize(address,address,address) external'
]);
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"
}
];
const publicClient = createPublicClient({
chain: arbitrumSepolia,
transport: http('https://sepolia-rollup.arbitrum.io/rpc')
});
async function checkLending() {
console.log('🔍 检查 Lending 合约设置\n');
try {
// 检查 owner
const owner = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'owner'
});
console.log('1⃣ Lending Owner:', owner);
} catch (error) {
console.log('1⃣ ❌ 读取 owner 失败');
}
// 尝试读取configurator地址
const getters = ['configurator', 'getConfigurator'];
let foundConfigurator = null;
for (const getter of getters) {
try {
console.log(`\n2⃣ 尝试调用 ${getter}()...`);
const configuratorAddr = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: getter
});
console.log(`${getter}() = ${configuratorAddr}`);
console.log(` 期望地址: ${CONFIGURATOR_ADDRESS}`);
console.log(` 匹配: ${configuratorAddr.toLowerCase() === CONFIGURATOR_ADDRESS.toLowerCase() ? '✅' : '❌'}`);
foundConfigurator = configuratorAddr;
if (configuratorAddr.toLowerCase() !== CONFIGURATOR_ADDRESS.toLowerCase()) {
console.log('\n⚠ 警告: Configurator 地址不匹配!');
console.log('💡 Lending 合约指向了不同的 Configurator');
console.log(` Lending 中的: ${configuratorAddr}`);
console.log(` 前端使用的: ${CONFIGURATOR_ADDRESS}`);
}
break;
} catch (error) {
console.log(`${getter}() 不存在或调用失败`);
}
}
if (!foundConfigurator) {
console.log('\n⚠ 未找到 Configurator 地址!');
console.log('💡 Lending 合约可能需要先通过 setConfigurator() 设置 Configurator 地址\n');
}
// 检查是否暂停
try {
const isPaused = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'paused'
});
console.log('\n3⃣ 系统暂停状态:', isPaused ? '已暂停' : '运行中');
} catch (error) {
console.log('\n3⃣ ❌ 读取暂停状态失败');
}
// 检查流动性
try {
const liquidity = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'getTotalSupply'
});
console.log('4⃣ 总供应量:', (Number(liquidity) / 1e6).toFixed(2), 'USDC');
} catch (error) {
console.log('4⃣ ❌ 读取总供应量失败');
}
// 检查系统数据查询函数
console.log('\n📊 系统数据查询:');
try {
const totalBorrow = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'getTotalBorrow'
});
console.log(' 总借款:', (Number(totalBorrow) / 1e6).toFixed(2), 'USDC');
} catch (error) {
console.log(' ❌ getTotalBorrow() 调用失败');
}
try {
const utilization = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'getUtilization'
});
console.log(' 资金利用率:', (Number(utilization) / 1e18 * 100).toFixed(2), '%');
} catch (error) {
console.log(' ❌ getUtilization() 调用失败');
}
try {
const borrowRate = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'getBorrowRate'
});
const borrowAPR = (Number(borrowRate) / 1e18 * 100).toFixed(2);
console.log(' 借款年利率:', borrowAPR, '%');
} catch (error) {
console.log(' ❌ getBorrowRate() 调用失败');
}
try {
const utilization = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'getUtilization'
});
const supplyRate = await publicClient.readContract({
address: LENDING_PROXY,
abi: LENDING_ABI,
functionName: 'getSupplyRate',
args: [utilization]
});
const supplyAPR = (Number(supplyRate) / 1e18 * 100).toFixed(2);
console.log(' 存款年利率:', supplyAPR, '%');
} catch (error) {
console.log(' ❌ getSupplyRate() 调用失败');
}
// 检查 Configurator 配置
console.log('\n⚙ Configurator 配置:');
try {
const config = await publicClient.readContract({
address: CONFIGURATOR_ADDRESS,
abi: CONFIGURATOR_ABI,
functionName: 'getConfiguration',
args: [LENDING_PROXY]
});
console.log(' 基础资产:', config.baseToken);
console.log(' 价格源:', config.lendingPriceSource);
console.log(' 抵押品资产数量:', config.assetConfigs.length);
config.assetConfigs.forEach((asset, index) => {
console.log(`\n 抵押品 ${index + 1}:`);
console.log(` 地址: ${asset.asset}`);
console.log(` 精度: ${asset.decimals}`);
console.log(` 借款抵押率: ${(Number(asset.borrowCollateralFactor) / 1e18 * 100).toFixed(2)}%`);
console.log(` 清算抵押率: ${(Number(asset.liquidateCollateralFactor) / 1e18 * 100).toFixed(2)}%`);
console.log(` 清算奖励: ${(Number(asset.liquidationFactor) / 1e18 * 100).toFixed(2)}%`);
console.log(` 供应上限: ${(Number(asset.supplyCap) / (10 ** asset.decimals)).toFixed(2)}`);
});
} catch (error) {
console.log(' ❌ 读取 Configurator 配置失败:', error.message);
}
console.log('\n💡 总结:');
console.log(' - 检查 Lending 合约是否正确设置了 Configurator 地址');
console.log(' - 检查 Configurator 合约是否正确设置了 Lending 地址');
console.log(' - 这两个合约需要相互关联才能正常工作');
}
checkLending();