Skip to content

Commit

Permalink
Update(Ringswap): Add fields support expanding to ETH (#603)
Browse files Browse the repository at this point in the history
  • Loading branch information
sunspirit99 authored Nov 21, 2024
1 parent b2f8e3f commit 5d5ab24
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 22 deletions.
60 changes: 55 additions & 5 deletions pkg/liquidity-source/ringswap/pool_simulator.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@ import (
)

var (
ErrTokenSwapNotAllowed = errors.New("cannot swap between original token and wrapped token")
ErrReserveIndexOutOfBounds = errors.New("reserve index out of bounds")
ErrTokenIndexOutOfBounds = errors.New("token index out of bounds")
ErrTokenSwapNotAllowed = errors.New("cannot swap between original token and wrapped token")
)

type (
Expand Down Expand Up @@ -76,12 +78,20 @@ func (s *PoolSimulator) CalcAmountOut(param poolpkg.CalcAmountOutParams) (*poolp
return nil, uniswapv2.ErrInsufficientInputAmount
}

reserveIn, overflow := uint256.FromBig(s.Pool.Info.Reserves[indexIn%2])
reserveIndex := indexIn % 2
if reserveIndex >= len(s.Pool.Info.Reserves) {
return nil, ErrReserveIndexOutOfBounds
}
reserveIn, overflow := uint256.FromBig(s.Pool.Info.Reserves[reserveIndex])
if overflow {
return nil, uniswapv2.ErrInvalidReserve
}

reserveOut, overflow := uint256.FromBig(s.Pool.Info.Reserves[indexOut%2])
reserveOutIndex := indexOut % 2
if reserveOutIndex >= len(s.Pool.Info.Reserves) {
return nil, ErrReserveIndexOutOfBounds
}
reserveOut, overflow := uint256.FromBig(s.Pool.Info.Reserves[reserveOutIndex])
if overflow {
return nil, uniswapv2.ErrInvalidReserve
}
Expand All @@ -95,12 +105,26 @@ func (s *PoolSimulator) CalcAmountOut(param poolpkg.CalcAmountOutParams) (*poolp
return nil, uniswapv2.ErrInsufficientLiquidity
}

wTokenInIndex := indexIn%2 + 2
if wTokenInIndex >= len(s.Pool.Info.Tokens) {
return nil, ErrTokenIndexOutOfBounds
}
wTokenIn := s.Pool.Info.Tokens[wTokenInIndex]

wTokenOutIndex := indexOut%2 + 2
if wTokenOutIndex >= len(s.Pool.Info.Tokens) {
return nil, ErrTokenIndexOutOfBounds
}
wTokenOut := s.Pool.Info.Tokens[wTokenOutIndex]

return &poolpkg.CalcAmountOutResult{
TokenAmountOut: &poolpkg.TokenAmount{Token: s.Pool.Info.Tokens[indexOut], Amount: amountOut.ToBig()},
// NOTE: we don't use fee to update balance so that we don't need to calculate it. I put it number.Zero to avoid null pointer exception
Fee: &poolpkg.TokenAmount{Token: s.Pool.Info.Tokens[indexIn], Amount: integer.Zero()},
Gas: s.gas.Swap,
SwapInfo: SwapInfo{
WTokenIn: wTokenIn,
WTokenOut: wTokenOut,
IsToken0To1: indexIn%2 == 0,
IsWrapIn: indexIn < 2,
IsUnwrapOut: indexOut < 2,
Expand All @@ -119,6 +143,10 @@ func (s *PoolSimulator) CalcAmountIn(param poolpkg.CalcAmountInParams) (*poolpkg
return nil, uniswapv2.ErrInvalidToken
}

if indexIn%2 == indexOut%2 {
return nil, ErrTokenSwapNotAllowed
}

amountOut, overflow := uint256.FromBig(tokenAmountOut.Amount)
if overflow {
return nil, uniswapv2.ErrInvalidAmountOut
Expand All @@ -128,12 +156,20 @@ func (s *PoolSimulator) CalcAmountIn(param poolpkg.CalcAmountInParams) (*poolpkg
return nil, uniswapv2.ErrInsufficientOutputAmount
}

reserveIn, overflow := uint256.FromBig(s.Pool.Info.Reserves[indexIn%2])
reserveIndex := indexIn % 2
if reserveIndex >= len(s.Pool.Info.Reserves) {
return nil, ErrReserveIndexOutOfBounds
}
reserveIn, overflow := uint256.FromBig(s.Pool.Info.Reserves[reserveIndex])
if overflow {
return nil, uniswapv2.ErrInvalidReserve
}

reserveOut, overflow := uint256.FromBig(s.Pool.Info.Reserves[indexOut%2])
reserveOutIndex := indexOut % 2
if reserveOutIndex >= len(s.Pool.Info.Reserves) {
return nil, ErrReserveIndexOutOfBounds
}
reserveOut, overflow := uint256.FromBig(s.Pool.Info.Reserves[reserveOutIndex])
if overflow {
return nil, uniswapv2.ErrInvalidReserve
}
Expand Down Expand Up @@ -167,12 +203,26 @@ func (s *PoolSimulator) CalcAmountIn(param poolpkg.CalcAmountInParams) (*poolpkg
return nil, uniswapv2.ErrInvalidK
}

wTokenInIndex := indexIn%2 + 2
if wTokenInIndex >= len(s.Pool.Info.Tokens) {
return nil, ErrTokenIndexOutOfBounds
}
wTokenIn := s.Pool.Info.Tokens[wTokenInIndex]

wTokenOutIndex := indexOut%2 + 2
if wTokenOutIndex >= len(s.Pool.Info.Tokens) {
return nil, ErrTokenIndexOutOfBounds
}
wTokenOut := s.Pool.Info.Tokens[wTokenOutIndex]

return &poolpkg.CalcAmountInResult{
TokenAmountIn: &poolpkg.TokenAmount{Token: s.Pool.Info.Tokens[indexIn], Amount: amountIn.ToBig()},
// NOTE: we don't use fee to update balance so that we don't need to calculate it. I put it number.Zero to avoid null pointer exception
Fee: &poolpkg.TokenAmount{Token: s.Pool.Info.Tokens[indexIn], Amount: integer.Zero()},
Gas: s.gas.Swap,
SwapInfo: SwapInfo{
WTokenIn: wTokenIn,
WTokenOut: wTokenOut,
IsToken0To1: indexIn%2 == 0,
IsWrapIn: indexIn < 2,
IsUnwrapOut: indexOut < 2,
Expand Down
50 changes: 36 additions & 14 deletions pkg/liquidity-source/ringswap/pool_simulator_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,14 @@ func TestPoolSimulator_CalcAmountIn(t *testing.T) {
poolSimulator: PoolSimulator{
Pool: poolpkg.Pool{
Info: poolpkg.PoolInfo{
Address: "0x3041cbd36888becc7bbcbc0045e3b1f144466f5f",
Tokens: []string{"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0xdac17f958d2ee523a2206206994597c13d831ec7"},
Reserves: []*big.Int{utils.NewBig("100000000"), utils.NewBig("100000000")},
Address: "0x3041cbd36888becc7bbcbc0045e3b1f144466f5f",
Tokens: []string{
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"0xdac17f958d2ee523a2206206994597c13d831ec7",
"0x18755d2cec785ab87680edb8e117615e4b005430", // Wrapped token 0
"0x66714db8f3397c767d0a602458b5b4e3c0fe7dd1", // Wrapped token 1
},
Reserves: []*big.Int{utils.NewBig("100000000"), utils.NewBig("100000000"), utils.One, utils.One},
},
},
fee: number.NewUint256("3"),
Expand All @@ -236,9 +241,14 @@ func TestPoolSimulator_CalcAmountIn(t *testing.T) {
poolSimulator: PoolSimulator{
Pool: poolpkg.Pool{
Info: poolpkg.PoolInfo{
Address: "0x576cea6d4461fcb3a9d43e922c9b54c0f791599a",
Tokens: []string{"0x32a7c02e79c4ea1008dd6564b35f131428673c41", "0xdac17f958d2ee523a2206206994597c13d831ec7"},
Reserves: []*big.Int{utils.NewBig("100000000000000000000"), utils.NewBig("100000000")},
Address: "0x576cea6d4461fcb3a9d43e922c9b54c0f791599a",
Tokens: []string{
"0x32a7c02e79c4ea1008dd6564b35f131428673c41",
"0xdac17f958d2ee523a2206206994597c13d831ec7",
"0x18755d2cec785ab87680edb8e117615e4b005430", // Wrapped token 0
"0x66714db8f3397c767d0a602458b5b4e3c0fe7dd1", // Wrapped token 1
},
Reserves: []*big.Int{utils.NewBig("100000000000000000000"), utils.NewBig("100000000"), utils.One, utils.One},
},
},
fee: number.NewUint256("3"),
Expand Down Expand Up @@ -283,9 +293,14 @@ func TestPoolSimulator_UpdateBalance(t *testing.T) {
poolSimulator: PoolSimulator{
Pool: poolpkg.Pool{
Info: poolpkg.PoolInfo{
Address: "0x3041cbd36888becc7bbcbc0045e3b1f144466f5f",
Tokens: []string{"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", "0xdac17f958d2ee523a2206206994597c13d831ec7"},
Reserves: []*big.Int{utils.NewBig("10089138480746"), utils.NewBig("10066716097576")},
Address: "0x3041cbd36888becc7bbcbc0045e3b1f144466f5f",
Tokens: []string{
"0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48",
"0xdac17f958d2ee523a2206206994597c13d831ec7",
"0x18755d2cec785ab87680edb8e117615e4b005430", // Wrapped token 0
"0x66714db8f3397c767d0a602458b5b4e3c0fe7dd1", // Wrapped token 1
},
Reserves: []*big.Int{utils.NewBig("10089138480746"), utils.NewBig("10066716097576"), utils.One, utils.One},
},
},
fee: number.NewUint256("3"),
Expand All @@ -296,16 +311,21 @@ func TestPoolSimulator_UpdateBalance(t *testing.T) {
TokenAmountOut: poolpkg.TokenAmount{Token: "0xdac17f958d2ee523a2206206994597c13d831ec7", Amount: utils.NewBig("124570062")},
Fee: poolpkg.TokenAmount{Token: "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48", Amount: utils.NewBig("375674")},
},
expectedReserves: []*big.Int{utils.NewBig("10089263705492"), utils.NewBig("10066591527514")},
expectedReserves: []*big.Int{utils.NewBig("10089263705492"), utils.NewBig("10066591527514"), utils.One, utils.One},
},
{
name: "[swap1to0] it should return correct amountOut and fee",
poolSimulator: PoolSimulator{
Pool: poolpkg.Pool{
Info: poolpkg.PoolInfo{
Address: "0x576cea6d4461fcb3a9d43e922c9b54c0f791599a",
Tokens: []string{"0x32a7c02e79c4ea1008dd6564b35f131428673c41", "0xdac17f958d2ee523a2206206994597c13d831ec7"},
Reserves: []*big.Int{utils.NewBig("70361282326226590645832"), utils.NewBig("54150601005")},
Address: "0x576cea6d4461fcb3a9d43e922c9b54c0f791599a",
Tokens: []string{
"0x32a7c02e79c4ea1008dd6564b35f131428673c41",
"0xdac17f958d2ee523a2206206994597c13d831ec7",
"0x18755d2cec785ab87680edb8e117615e4b005430", // Wrapped token 0
"0x66714db8f3397c767d0a602458b5b4e3c0fe7dd1", // Wrapped token 1
},
Reserves: []*big.Int{utils.NewBig("70361282326226590645832"), utils.NewBig("54150601005"), utils.One, utils.One},
},
},
fee: number.NewUint256("3"),
Expand All @@ -315,7 +335,7 @@ func TestPoolSimulator_UpdateBalance(t *testing.T) {
TokenAmountIn: poolpkg.TokenAmount{Token: "0xdac17f958d2ee523a2206206994597c13d831ec7", Amount: utils.NewBig("124570062")},
TokenAmountOut: poolpkg.TokenAmount{Token: "0x32a7c02e79c4ea1008dd6564b35f131428673c41", Amount: utils.NewBig("161006857684289764421")},
},
expectedReserves: []*big.Int{utils.NewBig("70200275468542300881411"), utils.NewBig("54275171067")},
expectedReserves: []*big.Int{utils.NewBig("70200275468542300881411"), utils.NewBig("54275171067"), utils.One, utils.One},
},
}

Expand All @@ -325,6 +345,8 @@ func TestPoolSimulator_UpdateBalance(t *testing.T) {

assert.Equal(t, 0, tc.poolSimulator.Info.Reserves[0].Cmp(tc.expectedReserves[0]))
assert.Equal(t, 0, tc.poolSimulator.Info.Reserves[1].Cmp(tc.expectedReserves[1]))
assert.Equal(t, 0, tc.poolSimulator.Info.Reserves[2].Cmp(tc.expectedReserves[2]))
assert.Equal(t, 0, tc.poolSimulator.Info.Reserves[3].Cmp(tc.expectedReserves[3]))
})
}
}
Expand Down
8 changes: 5 additions & 3 deletions pkg/liquidity-source/ringswap/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ type Extra struct {
}

type SwapInfo struct {
IsToken0To1 bool `json:"isToken0To1"`
IsWrapIn bool `json:"isWrapIn"`
IsUnwrapOut bool `json:"isUnwrapOut"`
WTokenIn string `json:"wTokenIn"`
WTokenOut string `json:"wTokenOut"`
IsToken0To1 bool `json:"isToken0To1"`
IsWrapIn bool `json:"isWrapIn"`
IsUnwrapOut bool `json:"isUnwrapOut"`
}

0 comments on commit 5d5ab24

Please sign in to comment.