-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: Router의 PoC 추가 * Apply suggestions from code review Co-authored-by: Lee ByeongJun <lbj199874@gmail.com> * review 지적사항 수정 * MyRouter.Swap() error message 수정 --------- Co-authored-by: tolelom <tolelom@naver.com> Co-authored-by: Lee ByeongJun <lbj199874@gmail.com>
- Loading branch information
1 parent
7ba8127
commit dceaa95
Showing
12 changed files
with
251 additions
and
81 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,5 +2,4 @@ package currency | |
|
||
// Currency는 Token | NativeCurrency | ||
type Currency interface { | ||
Wrapped() Token | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -2,4 +2,5 @@ package currency | |
|
||
type Token struct { | ||
BaseCurrency | ||
address string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
package tokens | ||
|
||
import "router/core/currency" | ||
|
||
type Gnot struct { | ||
currency.NativeCurrency | ||
} | ||
|
||
func NewGnot(chainId1 int64) *Gnot { | ||
return &Gnot{ | ||
NativeCurrency: currency.NativeCurrency{ | ||
BaseCurrency: currency.BaseCurrency{ | ||
ChainId: chainId1, | ||
}, | ||
}, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package poc | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
) | ||
|
||
type MyRouter struct { | ||
network map[string]*Pool | ||
} | ||
|
||
func NewMyRouter(edges []*Pool) *MyRouter { | ||
router := &MyRouter{ | ||
network: make(map[string]*Pool), | ||
} | ||
|
||
for _, edge := range edges { | ||
router.network[edge.Address] = edge | ||
} | ||
|
||
return router | ||
} | ||
|
||
func (m *MyRouter) Swap(request SwapRequest) (SwapResult, error) { | ||
// poolName은 from:to가 아니라 to:from일 수 있다. | ||
poolName := request.FromToken + ":" + request.ToToken | ||
|
||
if pool, ok := m.network[poolName]; ok { | ||
fmt.Printf("pool found: %v\n", pool) | ||
|
||
reserveFromToken, reserveToToken := m.getReserveOfTokenFromPool(request.FromToken, request.ToToken, *pool) | ||
exchangedAmount := m.calculateAmountOfToToken(reserveFromToken, reserveToToken, request.AmountIn, *pool) | ||
|
||
//saveSwap() | ||
// TODO: 지금은 간이로 코드 작성하고 나중에 함수로 빼든 리팩토링 할 것 | ||
if pool.TokenA.Symbol == request.FromToken { | ||
pool.ReserveA += request.AmountIn | ||
pool.ReserveB += exchangedAmount | ||
} else { | ||
pool.ReserveA += exchangedAmount | ||
pool.ReserveB += request.AmountIn | ||
} | ||
|
||
return SwapResult{ | ||
AmountIn: request.AmountIn, | ||
AmountOut: math.Abs(exchangedAmount), | ||
}, nil | ||
} | ||
|
||
return SwapResult{}, fmt.Errorf("pool %s not found", poolName) | ||
} | ||
|
||
func (m *MyRouter) getReserveOfTokenFromPool(fromTokenName string, toTokenName string, pool Pool) (float64, float64) { | ||
if fromTokenName == pool.TokenA.Symbol { | ||
return pool.ReserveA, pool.ReserveB | ||
} | ||
return pool.ReserveB, pool.ReserveA | ||
} | ||
|
||
func (m *MyRouter) calculateAmountOfToToken(reserveFromToken, reserveToToken, amountIn float64, pool Pool) float64 { | ||
X := reserveFromToken | ||
Y := reserveToToken | ||
dX := amountIn | ||
|
||
K := X * Y | ||
L := math.Sqrt(K) | ||
P := X / Y | ||
|
||
X_ := X + dX | ||
P_ := (X_ / L) * (X_ / L) | ||
|
||
dY := L * (1/math.Sqrt(P_) - 1/math.Sqrt(P)) | ||
|
||
// X 코인이 dX개 만큼 증가했을 때 | ||
// Y 코인은 dY개 만큼 감소해야 한다. | ||
// X -> X + dX, Y -> Y + dY | ||
|
||
return dY | ||
} | ||
|
||
func (m *MyRouter) dijskrtra() { | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package poc | ||
|
||
import ( | ||
"fmt" | ||
"math" | ||
"testing" | ||
) | ||
|
||
func TestMyRouter(t *testing.T) { | ||
tokens := map[string]Token{ | ||
"a": Token{Symbol: "a"}, | ||
"b": Token{Symbol: "b"}, | ||
} | ||
|
||
tests := []struct { | ||
edges []*Pool | ||
requests []SwapRequest | ||
results []SwapResult | ||
}{ | ||
{ | ||
[]*Pool{ | ||
{"a:b", tokens["a"], tokens["b"], 4000, 1000}}, | ||
[]SwapRequest{ | ||
{"a", "b", 2000}}, | ||
[]SwapResult{ | ||
{2000.0, 2000.0 / 6.0}, | ||
}, | ||
}, | ||
} | ||
|
||
for _, test := range tests { | ||
t.Run("", func(t *testing.T) { | ||
router := NewMyRouter(test.edges) | ||
|
||
for i, request := range test.requests { | ||
result, err := router.Swap(request) | ||
if err != nil { | ||
t.Fatalf("Swap Error: can't find pool: %v:%v", request.FromToken, request.ToToken) | ||
} | ||
|
||
diff := math.Abs(result.AmountOut - test.results[i].AmountOut) | ||
tolerance := 0.00000001 | ||
if diff > tolerance { | ||
t.Fatalf("Swap: Unexpected Token output number, expected: %v, got %v", test.results[i].AmountOut, result.AmountOut) | ||
} | ||
fmt.Println(result) | ||
|
||
for _, pool := range router.network { | ||
fmt.Println(pool) | ||
} | ||
} | ||
}) | ||
} | ||
} |
Oops, something went wrong.