238 lines
8.9 KiB
JavaScript
238 lines
8.9 KiB
JavaScript
|
|
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();
|