多协议 DeFi 资产聚合追踪,支持 LP 仓位、借贷头寸、质押收益的实时计算与风险评估
┌─────────────────────────────────────────────────────────────┐ │ API Gateway (GraphQL) │ ├─────────────────────────────────────────────────────────────┤ │ Portfolio │ Position │ Yield │ Risk │ │ Service │ Calculator │ Tracker │ Analyzer │ ├─────────────────────────────────────────────────────────────┤ │ Protocol Adapters Layer │ │ ┌─────────┐ ┌─────────┐ ┌─────────┐ ┌─────────┐ │ │ │ Uniswap │ │ Aave │ │Compound │ │ Curve │ │ │ └─────────┘ └─────────┘ └─────────┘ └─────────┘ │ ├─────────────────────────────────────────────────────────────┤ │ The Graph Indexer │ Price Oracle │ PostgreSQL │ └─────────────────────────────────────────────────────────────┘
1// Position 表示 Uniswap V3 LP 仓位2type Position struct {3 TokenID *big.Int4 Token0 common.Address5 Token1 common.Address6 Fee *big.Int7 TickLower int328 TickUpper int329 Liquidity *big.Int10 Amount0 *big.Int11 Amount1 *big.Int12}13 14// CalculatePositionValue 计算仓位当前价值15func (s *UniswapV3Service) CalculatePositionValue(16 ctx context.Context,17 position *Position,18) (*PositionValue, error) {19 // 获取当前池子状态20 pool, err := s.getPoolState(ctx, position.Token0, position.Token1, position.Fee)21 if err != nil {22 return nil, fmt.Errorf("get pool state: %w", err)23 }24 25 // 计算当前 tick 下的代币数量26 amount0, amount1 := s.calculateAmounts(27 position.Liquidity,28 pool.CurrentTick,29 position.TickLower,30 position.TickUpper,31 pool.SqrtPriceX96,32 )33 34 // 获取代币价格35 price0, _ := s.priceOracle.GetPrice(ctx, position.Token0)36 price1, _ := s.priceOracle.GetPrice(ctx, position.Token1)37 38 // 计算总价值 (USD)39 value0 := new(big.Float).Mul(toFloat(amount0), price0)40 value1 := new(big.Float).Mul(toFloat(amount1), price1)41 totalValue := new(big.Float).Add(value0, value1)42 43 // 计算无常损失44 il := s.calculateImpermanentLoss(position, pool)45 46 return &PositionValue{47 Amount0: amount0,48 Amount1: amount1,49 TotalValueUSD: totalValue,50 ImpermanentLoss: il,51 FeesEarned: s.calculateFeesEarned(position),52 }, nil53}1// HealthFactor 计算 Aave 借贷健康度2type HealthFactor struct {3 Value float644 CollateralUSD float645 DebtUSD float646 LiquidationRisk string // "safe", "warning", "danger"7}8 9// MonitorLendingPosition 监控借贷仓位健康度10func (s *RiskService) MonitorLendingPosition(11 ctx context.Context,12 wallet common.Address,13) (*HealthFactor, error) {14 // 获取用户账户数据15 accountData, err := s.aavePool.GetUserAccountData(16 &bind.CallOpts{Context: ctx},17 wallet,18 )19 if err != nil {20 return nil, err21 }22 23 // 计算健康度 = 总抵押物 * 清算阈值 / 总债务24 healthFactor := new(big.Float).Quo(25 toFloat(accountData.HealthFactor),26 big.NewFloat(1e18),27 )28 hf, _ := healthFactor.Float64()29 30 // 评估风险等级31 var risk string32 switch {33 case hf >= 1.5:34 risk = "safe"35 case hf >= 1.1:36 risk = "warning"37 default:38 risk = "danger"39 }40 41 // 危险时发送告警42 if risk == "danger" {43 s.alertService.SendLiquidationWarning(ctx, wallet, hf)44 }45 46 return &HealthFactor{47 Value: hf,48 CollateralUSD: toUSD(accountData.TotalCollateralBase),49 DebtUSD: toUSD(accountData.TotalDebtBase),50 LiquidationRisk: risk,51 }, nil52}