From c24ff182c81f5d515549f8689e30932b444de038 Mon Sep 17 00:00:00 2001 From: tolelom Date: Wed, 4 Sep 2024 14:02:02 +0900 Subject: [PATCH] =?UTF-8?q?PoC=20=EC=A0=9C=EC=9E=91=20=EC=99=84=EB=A3=8C?= =?UTF-8?q?=20=EB=B0=8F=20=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=20=EC=99=84=EB=A3=8C(=ED=85=8C=EC=8A=A4=ED=8A=B8=20=EC=BC=80?= =?UTF-8?q?=EC=9D=B4=EC=8A=A4=EB=8A=94=20=EB=8D=94=20=EC=B6=94=EA=B0=80?= =?UTF-8?q?=ED=95=98=EB=A9=B4=20=EC=A2=8B=EC=9D=8C)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/alpha_router.go | 45 +++++++++++++++++++++++++------------------ core/trade.go | 2 +- poc/my_router.go | 16 +++++++++++---- poc/my_router_test.go | 24 ++++++++++++++++++----- poc/pool.go | 4 +--- poc/swap_request.go | 2 +- 6 files changed, 60 insertions(+), 33 deletions(-) diff --git a/core/alpha_router.go b/core/alpha_router.go index 8090f24..53d33f9 100644 --- a/core/alpha_router.go +++ b/core/alpha_router.go @@ -15,46 +15,49 @@ func NewAlphaRouter(params AlphaRouterParams) *AlphaRouter { func (a *AlphaRouter) route( baseCurrency currency.Currency, quoteCurrency currency.Currency, - amount float64, + amount float64, // todo: float64 -> fraction tradeType TradeType, swapConfig SwapOptions, + routerConfig AlphaRouterConfig, ) SwapRoute { - originalAmount := amount + //originalAmount := amount // for save - currencyIn, currencyOut := a.determineCurrencyInOutFromTradeType(tradeType, baseCurrency, quoteCurrency) + //currencyIn, currencyOut := a.determineCurrencyInOutFromTradeType(tradeType, baseCurrency, quoteCurrency) // token은 currency의 wrapped된 버전이다. - tokenIn := currencyIn.GetToken() - tokenOut := currencyOut.GetToken() + //tokenIn := currencyIn.GetToken() + //tokenOut := currencyOut.GetToken() // 왠만하면 함수로 뺄 것 // 내용 이해 필요 if tradeType == EXACT_OUTPUT { - portionAmount, portionErr := a.portionProvider.GetPortionAmount( - amount, - tradeType, - swapConfig, - ) + portionAmount, portionErr := a.portionProvider.GetPortionAmount(amount, tradeType, swapConfig) if portionErr == nil && portionAmount > 0 { + // In case of exact out swap, before we route, we need to make sure that the + // token out amount accounts for flat portion, and token in amount after the best swap route contains the token in equivalent of portion. + // In other words, in case a pool's LP fee bps is lower than the portion bps (0.01%/0.05% for v3), a pool can go insolvency. + // This is because instead of the swapper being responsible for the portion, + // the pool instead gets responsible for the portion. + // The addition below avoids that situation. amount += portionAmount } } - // routing config 다루는 부분 패스 - routingConfig := AlphaRouterConfig{} + // routing config merge다루는 부분 패스 + //routerConfig = setRouterConfig(routingConfig, chainId) // tokenIn 또는 tokenOut과 동일한 값... - quoteToken := quoteCurrency.GetToken() + //quoteToken := quoteCurrency.GetToken() // main logic? - routes := a.getSwapRouteFromChain(tokenIn, tokenOut, amount, tradeType, routingConfig) + //routes := a.getSwapRouteFromChain(tokenIn, tokenOut, amount, tradeType, routingConfig) - if routes == nil { - // todo: error 처리 해 줄 것 - } + //if routes == nil { + // // todo: error 처리 해 줄 것 + //} - trade := a.buildTrade(currencyIn, currencyOut, tradeType, routes) + //trade := a.buildTrade(currencyIn, currencyOut, tradeType, routes) swapRoute := a.buildSwapRoute() return swapRoute @@ -73,7 +76,7 @@ func (a *AlphaRouter) determineCurrencyInOutFromTradeType( // todo: goroutine func (a *AlphaRouter) getSwapRouteFromChain(tokenIn, tokenOut currency.Token, amount float64, tradeType TradeType, routingConfig AlphaRouterConfig) *BestSwapRoute { - percents, amount := a.getAmountDistribution(amount, routingConfig) + //percents, amount := a.getAmountDistribution(amount, routingConfig) return &BestSwapRoute{} } @@ -91,3 +94,7 @@ func (a *AlphaRouter) buildTrade(currencyIn currency.Currency, currencyOut curre func (a *AlphaRouter) buildSwapRoute() SwapRoute { return SwapRoute{} } + +func (a *AlphaRouter) setRouterConfig(routerConfig AlphaRouterConfig, chainId int) AlphaRouterConfig { + return AlphaRouterConfig{} +} diff --git a/core/trade.go b/core/trade.go index ca1fff0..805e0b8 100644 --- a/core/trade.go +++ b/core/trade.go @@ -1,6 +1,6 @@ package core type Trade struct { - v3Routes V3Routes + //v3Routes V3Routes tradeType TradeType } diff --git a/poc/my_router.go b/poc/my_router.go index c3609d0..cf8acd9 100644 --- a/poc/my_router.go +++ b/poc/my_router.go @@ -5,6 +5,8 @@ import ( "math" ) +// MyRouter +// router PoC type MyRouter struct { network map[string]*Pool adj map[string][]string @@ -35,11 +37,14 @@ func (m *MyRouter) Route(request SwapRequest) ([]SwapResult, error) { //return m.findRouteV2(startTokenSymbol, endTokenSymbol, AmountIn, 1) } +// findRouteV1 +// 두 토큰을 direct swap한다 func (m *MyRouter) findRouteV1(request SwapRequest) ([]SwapResult, error) { return m.swap(request.FromTokenSymbol, request.ToTokenSymbol, request.AmountIn) } -// 경로가 maxLength 이하의 길이인 경로를 탐색해 route를 구한다. +// findRouteV2 +// 경로가 maxLength 이하의 길이인 경로를 탐색해 route를 구한다 func (m *MyRouter) findRouteV2(request SwapRequest, maxLength int, routes []SwapResult) ([]SwapResult, error) { startTokenSymbol, beforeTokenSymbol, amountIn := m.setSymbolAndAmountIn(request, routes) if startTokenSymbol == request.ToTokenSymbol { @@ -60,8 +65,10 @@ func (m *MyRouter) findRouteV2(request SwapRequest, maxLength int, routes []Swap continue } - workablePath, _ := m.findRouteV2(request, maxLength, append(routes, route...)) - // TODO: 여기에 스왑한 내용 복구가 필요합니다! + workablePath, findRouteErr := m.findRouteV2(request, maxLength, append(routes, route...)) + if findRouteErr != nil { + continue + } if len(workablePath) != 0 && (bestPath == nil || (bestPath[len(bestPath)-1].AmountOut < workablePath[len(workablePath)-1].AmountOut)) { bestPath = workablePath @@ -71,6 +78,7 @@ func (m *MyRouter) findRouteV2(request SwapRequest, maxLength int, routes []Swap return bestPath, nil } +// setSymbolAndAmountIn func (m *MyRouter) setSymbolAndAmountIn(request SwapRequest, routes []SwapResult) (string, string, float64) { if routes == nil { // 처음 함수가 호출된 거라면 return request.FromTokenSymbol, "", request.AmountIn @@ -86,7 +94,6 @@ func (m *MyRouter) swap(fromTokenSymbol string, toTokenSymbol string, amountIn f poolName := fromTokenSymbol + ":" + toTokenSymbol if pool, ok := m.network[poolName]; ok { - //fmt.Printf("pool found: %v\n", pool) // for debug reserveFromToken, reserveToToken := m.getReserveOfTokenFromPool(fromTokenSymbol, toTokenSymbol, *pool) amountOut := m.calculateAmountOfToToken(reserveFromToken, reserveToToken, amountIn, *pool) @@ -104,6 +111,7 @@ func (m *MyRouter) swap(fromTokenSymbol string, toTokenSymbol string, amountIn f return nil, fmt.Errorf("pool %s not found", poolName) } +// saveSwap func (m *MyRouter) saveSwap(fromTokenSymbol string, amountIn, amountOut float64, pool *Pool) { if pool.TokenA.Symbol == fromTokenSymbol { pool.ReserveA += amountIn diff --git a/poc/my_router_test.go b/poc/my_router_test.go index 1c9cf4b..6866c6d 100644 --- a/poc/my_router_test.go +++ b/poc/my_router_test.go @@ -64,9 +64,10 @@ func TestMyRouterV2(t *testing.T) { } tests := []struct { - edges []*Pool - requests []SwapRequest - results []SwapResult + edges []*Pool + requests []SwapRequest + results []SwapResult + maxSearchLength int }{ { []*Pool{ @@ -76,8 +77,21 @@ func TestMyRouterV2(t *testing.T) { []SwapRequest{ {"a", "c", 2000}}, []SwapResult{ - {"a", "c", 2000.0, 571.4285714285}, + {"a", "c", 2000, 571.4285714285}, + }, + 2, + }, + { + []*Pool{ + {"a:b", tokens["a"], tokens["b"], 4000, 1000}, + {"a:c", tokens["a"], tokens["c"], 2000, 1000}, + {"b:c", tokens["b"], tokens["c"], 2000, 4000}}, + []SwapRequest{ + {"a", "c", 2000}}, + []SwapResult{ + {"a", "c", 2000, 500}, }, + 1, }, } @@ -86,7 +100,7 @@ func TestMyRouterV2(t *testing.T) { router := NewMyRouter(test.edges) for i, request := range test.requests { - result, err := router.findRouteV2(request, 10, nil) + result, err := router.findRouteV2(request, test.maxSearchLength, nil) if err != nil { t.Fatalf("Router: can't find path: %v:%v", request.FromTokenSymbol, request.ToTokenSymbol) } diff --git a/poc/pool.go b/poc/pool.go index 12c4707..202f01e 100644 --- a/poc/pool.go +++ b/poc/pool.go @@ -1,11 +1,9 @@ package poc -// Pool -// kind of edge type Pool struct { Address string - TokenA Token // 효율을 위해서는 포인터로 가져오는게 좋을만 하다. + TokenA Token // Todo: 효율을 위해서는 포인터로 가져오는게 좋을만 하다. TokenB Token ReserveA float64 diff --git a/poc/swap_request.go b/poc/swap_request.go index d146258..31e2ba2 100644 --- a/poc/swap_request.go +++ b/poc/swap_request.go @@ -5,5 +5,5 @@ type SwapRequest struct { ToTokenSymbol string AmountIn float64 //MinAmountOut int - //UserAddress string // option + //UserAddress string // optional }