聚合 Uniswap/Sushiswap/Curve 等 DEX 报价,寻找最优兑换路径
┌──────────────┐ ┌─────────────┐ ┌──────────────┐
│ Clients │────▶│ GraphQL/ │────▶│ DEX Router │
│ (API/gRPC) │ │ gRPC API │ │ Engine │
└──────────────┘ └─────────────┘ └──────────────┘
│
┌───────────────────┼───────────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Uniswap V2│ │Uniswap V3│ │ Curve │
│ Adapter │ │ Adapter │ │ Adapter │
└──────────┘ └──────────┘ └──────────┘
1type DEXAdapter interface {2 Name() string3 GetPools(ctx context.Context, tokenA, tokenB common.Address) ([]*Pool, error)4 GetQuote(ctx context.Context, pool *Pool, amountIn *big.Int, zeroForOne bool) (*Quote, error)5 BuildSwapTx(ctx context.Context, params *SwapParams) (*types.Transaction, error)6}7 8type Pool struct {9 Address common.Address10 DEX string11 Token0 common.Address12 Token1 common.Address13 Reserve0 *big.Int14 Reserve1 *big.Int15 Fee uint3216}17 18type Quote struct {19 AmountOut *big.Int20 PriceImpact float6421 Fee *big.Int22 Route []*Pool23}1func (r *Router) FindBestRoute(ctx context.Context, tokenIn, tokenOut common.Address, amountIn *big.Int) (*Route, error) {2 // 获取所有可能的池3 pools, err := r.getAllPools(ctx, tokenIn, tokenOut)4 if err != nil {5 return nil, err6 }7 8 // 构建交易图9 graph := r.buildGraph(pools)10 11 // 使用修改的 Dijkstra 算法寻找最优路径12 bestRoute := r.dijkstraWithSplit(graph, tokenIn, tokenOut, amountIn)13 14 // 计算最终输出和价格影响15 totalOutput := big.NewInt(0)16 for _, split := range bestRoute.Splits {17 quote, _ := r.getQuoteForPath(ctx, split.Path, split.Amount)18 totalOutput.Add(totalOutput, quote.AmountOut)19 }20 21 return &Route{22 TokenIn: tokenIn,23 TokenOut: tokenOut,24 AmountIn: amountIn,25 AmountOut: totalOutput,26 Splits: bestRoute.Splits,27 PriceImpact: r.calculatePriceImpact(amountIn, totalOutput, tokenIn, tokenOut),28 }, nil29}