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()