Skip to content

Commit

Permalink
Fix/kep 185 upgrade versionv040 (#6)
Browse files Browse the repository at this point in the history
* Support EncodeRouteToPath

* Fix type error in selfpermit arguments, add test for selfpermit.

* Fix the tick index mismatch in GetTick(daoleno#4)

* Support SwapQuoter

* Add custom input to MinimumAmountIn/Out

* Upgrade sdk-core. Fix broken ether usage.

* [WIP] SwapRouter

* Applied core changes regarding currency abstraction (#8)

* Applied core changes regarding currency abstraction

* Updated core lib

* add example code (#10)

* upgrade go mod

* Broken link in samples (#13)

* Fixed broken link in samples

* fix(trade): fix sortedInsert bug (#14)

* test(swaprouter): SingleTradeInput & MultipleTradeInput unit test

* test(swaprouter): trade with multiple routes unit test

* feat(staker): uniswap v3 staker feature

* optimize tick math (#19)

* change module and add gitignore

* Revert "refactor: avoid using panic (it crashes the API) (#5)"

This reverts commit 47808c2.

* Revert "fix: handle case when a pool is added liquidity in full range (#4)"

This reverts commit 66e8ef2.

* Revert "refactor: Improve searching for next tick (#3)"

This reverts commit 54669aa.

* Revert "refactor: Change package organization"

This reverts commit 905a578.

* Revert "refactor: Remove Unused Code"

This reverts commit 3190335.

* Revert "refactor: Rename Package"

This reverts commit c249ea6.

* Revert "fix: GetTick Function"

This reverts commit f363610.

Co-authored-by: daoleno <[email protected]>
Co-authored-by: Vaulin Alexandr <[email protected]>
Co-authored-by: 李亚夫 <[email protected]>
Co-authored-by: Archil <[email protected]>
Co-authored-by: xiang <[email protected]>
Co-authored-by: Nathaniel Blakely <[email protected]>
Co-authored-by: DoanNamTruc <[email protected]>
  • Loading branch information
8 people authored Dec 28, 2022
1 parent 47808c2 commit bcca8c3
Show file tree
Hide file tree
Showing 71 changed files with 15,588 additions and 1,238 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ jobs:
test:
strategy:
matrix:
go-version: [1.16.x, 1.17.x]
go-version: [1.18.x]
os: [ubuntu-latest, macos-latest, windows-latest]
runs-on: ${{ matrix.os }}
steps:
Expand All @@ -23,7 +23,7 @@ jobs:
- name: Install Go
uses: actions/setup-go@v2
with:
go-version: 1.17.x
go-version: 1.18.x
- name: Checkout code
uses: actions/checkout@v2
- uses: actions/cache@v2
Expand Down
36 changes: 36 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# OS specific
.DS_Store

# Dependency directories
vendor/

# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
*.dylib

# Test binary, built with `go test -c`
*.test

# Output of the go coverage tool, specifically when used with LiteIDE
*.out

# Go workspace file
go.work

# IDE configuration files
.idea/
.vscode/launch.json

# Test result
test/logs
test/result

# Environment Variables
.env

# Miscellaneous
command
app
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
## Installation

```sh
go get github.com/KyberNetwork/uniswapv3-sdk
go get github.com/daoleno/uniswapv3-sdk
```

## Usage
Expand All @@ -23,10 +23,10 @@ import (
"fmt"
"math/big"

core "github.com/KyberNetwork/uniswap-sdk-core/entities"
"github.com/KyberNetwork/uniswapv3-sdk/constants"
"github.com/KyberNetwork/uniswapv3-sdk/entities"
"github.com/KyberNetwork/uniswapv3-sdk/utils"
core "github.com/daoleno/uniswap-sdk-core/entities"
"github.com/daoleno/uniswapv3-sdk/constants"
"github.com/daoleno/uniswapv3-sdk/entities"
"github.com/daoleno/uniswapv3-sdk/utils"
"github.com/ethereum/go-ethereum/common"
)

Expand Down Expand Up @@ -64,7 +64,7 @@ func main() {
}

// USDC -> DAI
outputAmount := core.FromRawAmount(DAI.Currency, big.NewInt(98))
outputAmount := core.FromRawAmount(DAI, big.NewInt(98))
inputAmount, _, err := pool.GetInputAmount(outputAmount, nil)
if err != nil {
panic(err)
Expand Down
2 changes: 1 addition & 1 deletion constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package constants
import (
"math/big"

"github.com/KyberNetwork/uniswap-sdk-core/entities"
"github.com/daoleno/uniswap-sdk-core/entities"
"github.com/ethereum/go-ethereum/common"
)

Expand Down
2 changes: 1 addition & 1 deletion entities/nearestusabletick.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package entities
import (
"math"

"github.com/KyberNetwork/uniswapv3-sdk/utils"
"github.com/daoleno/uniswapv3-sdk/utils"
)

/**
Expand Down
3 changes: 1 addition & 2 deletions entities/nearestusabletick_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@ package entities
import (
"testing"

"github.com/daoleno/uniswapv3-sdk/utils"
"github.com/stretchr/testify/assert"

"github.com/KyberNetwork/uniswapv3-sdk/utils"
)

func TestNearestUsableTick(t *testing.T) {
Expand Down
51 changes: 22 additions & 29 deletions entities/pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,10 @@ import (
"errors"
"math/big"

"github.com/KyberNetwork/uniswap-sdk-core/entities"
"github.com/daoleno/uniswap-sdk-core/entities"
"github.com/daoleno/uniswapv3-sdk/constants"
"github.com/daoleno/uniswapv3-sdk/utils"
"github.com/ethereum/go-ethereum/common"

"github.com/KyberNetwork/uniswapv3-sdk/constants"
"github.com/KyberNetwork/uniswapv3-sdk/utils"
)

var (
Expand Down Expand Up @@ -102,15 +101,15 @@ func NewPool(tokenA, tokenB *entities.Token, fee constants.FeeAmount, sqrtRatioX
* @returns True if token is either token0 or token
*/
func (p *Pool) InvolvesToken(token *entities.Token) bool {
return p.Token0.Equals(token) || p.Token1.Equals(token)
return p.Token0.Equal(token) || p.Token1.Equal(token)
}

// Token0Price returns the current mid price of the pool in terms of token0, i.e. the ratio of token1 over token0
func (p *Pool) Token0Price() *entities.Price {
if p.token0Price != nil {
return p.token0Price
}
p.token0Price = entities.NewPrice(p.Token0.Currency, p.Token1.Currency, constants.Q192, new(big.Int).Mul(p.SqrtRatioX96, p.SqrtRatioX96))
p.token0Price = entities.NewPrice(p.Token0, p.Token1, constants.Q192, new(big.Int).Mul(p.SqrtRatioX96, p.SqrtRatioX96))
return p.token0Price
}

Expand All @@ -119,7 +118,7 @@ func (p *Pool) Token1Price() *entities.Price {
if p.token1Price != nil {
return p.token1Price
}
p.token1Price = entities.NewPrice(p.Token1.Currency, p.Token0.Currency, new(big.Int).Mul(p.SqrtRatioX96, p.SqrtRatioX96), constants.Q192)
p.token1Price = entities.NewPrice(p.Token1, p.Token0, new(big.Int).Mul(p.SqrtRatioX96, p.SqrtRatioX96), constants.Q192)
return p.token1Price
}

Expand All @@ -132,15 +131,15 @@ func (p *Pool) PriceOf(token *entities.Token) (*entities.Price, error) {
if !p.InvolvesToken(token) {
return nil, ErrTokenNotInvolved
}
if p.Token0.Equals(token) {
if p.Token0.Equal(token) {
return p.Token0Price(), nil
}
return p.Token1Price(), nil
}

// ChainId returns the chain ID of the tokens in the pool.
func (p *Pool) ChainID() uint {
return p.Token0.ChainID
return p.Token0.ChainId()
}

/**
Expand All @@ -150,9 +149,10 @@ func (p *Pool) ChainID() uint {
* @returns The output amount and the pool with updated state
*/
func (p *Pool) GetOutputAmount(inputAmount *entities.CurrencyAmount, sqrtPriceLimitX96 *big.Int) (*entities.CurrencyAmount, *Pool, error) {
// TODO: check involoves token
// invariant(this.involvesToken(inputAmount.currency), 'TOKEN')
zeroForOne := inputAmount.Currency.Equal(p.Token0.Currency)
if !(inputAmount.Currency.IsToken() && p.InvolvesToken(inputAmount.Currency.Wrapped())) {
return nil, nil, ErrTokenNotInvolved
}
zeroForOne := inputAmount.Currency.Equal(p.Token0)
outputAmount, sqrtRatioX96, liquidity, tickCurrent, err := p.swap(zeroForOne, inputAmount.Quotient(), sqrtPriceLimitX96)
if err != nil {
return nil, nil, err
Expand All @@ -167,7 +167,7 @@ func (p *Pool) GetOutputAmount(inputAmount *entities.CurrencyAmount, sqrtPriceLi
if err != nil {
return nil, nil, err
}
return entities.FromRawAmount(outputToken.Currency, new(big.Int).Mul(outputAmount, constants.NegativeOne)), pool, nil
return entities.FromRawAmount(outputToken, new(big.Int).Mul(outputAmount, constants.NegativeOne)), pool, nil
}

/**
Expand All @@ -177,9 +177,10 @@ func (p *Pool) GetOutputAmount(inputAmount *entities.CurrencyAmount, sqrtPriceLi
* @returns The input amount and the pool with updated state
*/
func (p *Pool) GetInputAmount(outputAmount *entities.CurrencyAmount, sqrtPriceLimitX96 *big.Int) (*entities.CurrencyAmount, *Pool, error) {
// TODO: check involoves token
// invariant(outputAmount.currency.isToken && this.involvesToken(outputAmount.currency), 'TOKEN')
zeroForOne := outputAmount.Currency.Equal(p.Token1.Currency)
if !(outputAmount.Currency.IsToken() && p.InvolvesToken(outputAmount.Currency.Wrapped())) {
return nil, nil, ErrTokenNotInvolved
}
zeroForOne := outputAmount.Currency.Equal(p.Token1)
inputAmount, sqrtRatioX96, liquidity, tickCurrent, err := p.swap(zeroForOne, new(big.Int).Mul(outputAmount.Quotient(), constants.NegativeOne), sqrtPriceLimitX96)
if err != nil {
return nil, nil, err
Expand All @@ -194,7 +195,7 @@ func (p *Pool) GetInputAmount(outputAmount *entities.CurrencyAmount, sqrtPriceLi
if err != nil {
return nil, nil, err
}
return entities.FromRawAmount(inputToken.Currency, inputAmount), pool, nil
return entities.FromRawAmount(inputToken, inputAmount), pool, nil
}

/**
Expand All @@ -217,14 +218,14 @@ func (p *Pool) swap(zeroForOne bool, amountSpecified, sqrtPriceLimitX96 *big.Int
}

if zeroForOne {
if sqrtPriceLimitX96.Cmp(utils.MinSqrtRatio) < 0 {
if sqrtPriceLimitX96.Cmp(utils.MinSqrtRatio) <= 0 {
return nil, nil, nil, 0, ErrSqrtPriceLimitX96TooLow
}
if sqrtPriceLimitX96.Cmp(p.SqrtRatioX96) >= 0 {
return nil, nil, nil, 0, ErrSqrtPriceLimitX96TooHigh
}
} else {
if sqrtPriceLimitX96.Cmp(utils.MaxSqrtRatio) > 0 {
if sqrtPriceLimitX96.Cmp(utils.MaxSqrtRatio) >= 0 {
return nil, nil, nil, 0, ErrSqrtPriceLimitX96TooHigh
}
if sqrtPriceLimitX96.Cmp(p.SqrtRatioX96) <= 0 {
Expand Down Expand Up @@ -258,10 +259,7 @@ func (p *Pool) swap(zeroForOne bool, amountSpecified, sqrtPriceLimitX96 *big.Int
// because each iteration of the while loop rounds, we can't optimize this code (relative to the smart contract)
// by simply traversing to the next available tick, we instead need to exactly replicate
// tickBitmap.nextInitializedTickWithinOneWord
step.tickNext, step.initialized, err = p.TickDataProvider.NextInitializedTickIndex(state.tick, zeroForOne)
if err != nil {
return nil, nil, nil, 0, err
}
step.tickNext, step.initialized = p.TickDataProvider.NextInitializedTickWithinOneWord(state.tick, zeroForOne, p.tickSpacing())

if step.tickNext < utils.MinTick {
step.tickNext = utils.MinTick
Expand Down Expand Up @@ -305,12 +303,7 @@ func (p *Pool) swap(zeroForOne bool, amountSpecified, sqrtPriceLimitX96 *big.Int
if state.sqrtPriceX96.Cmp(step.sqrtPriceNextX96) == 0 {
// if the tick is initialized, run the tick transition
if step.initialized {
tick, err := p.TickDataProvider.GetTick(step.tickNext)
if err != nil {
return nil, nil, nil, 0, err
}

liquidityNet := tick.LiquidityNet
liquidityNet := p.TickDataProvider.GetTick(step.tickNext).LiquidityNet
// if we're moving leftward, we interpret liquidityNet as the opposite sign
// safe because liquidityNet cannot be type(int128).min
if zeroForOne {
Expand Down
23 changes: 11 additions & 12 deletions entities/pool_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import (
"math/big"
"testing"

"github.com/KyberNetwork/uniswap-sdk-core/entities"
"github.com/daoleno/uniswap-sdk-core/entities"
"github.com/daoleno/uniswapv3-sdk/constants"
"github.com/daoleno/uniswapv3-sdk/utils"
"github.com/ethereum/go-ethereum/common"
"github.com/stretchr/testify/assert"

"github.com/KyberNetwork/uniswapv3-sdk/constants"
"github.com/KyberNetwork/uniswapv3-sdk/utils"
)

var (
Expand Down Expand Up @@ -142,42 +141,42 @@ func TestGetOutputAmount(t *testing.T) {
pool := newTestPool()

// USDC -> DAI
inputAmount := entities.FromRawAmount(USDC.Currency, big.NewInt(100))
inputAmount := entities.FromRawAmount(USDC, big.NewInt(100))
outputAmount, _, err := pool.GetOutputAmount(inputAmount, nil)
if err != nil {
t.Fatal(err)
}
assert.True(t, outputAmount.Currency.Equal(DAI.Currency))
assert.True(t, outputAmount.Currency.Equal(DAI))
assert.Equal(t, outputAmount.Quotient(), big.NewInt(98))

// DAI -> USDC
inputAmount = entities.FromRawAmount(DAI.Currency, big.NewInt(100))
inputAmount = entities.FromRawAmount(DAI, big.NewInt(100))
outputAmount, _, err = pool.GetOutputAmount(inputAmount, nil)
if err != nil {
t.Fatal(err)
}
assert.True(t, outputAmount.Currency.Equal(USDC.Currency))
assert.True(t, outputAmount.Currency.Equal(USDC))
assert.Equal(t, outputAmount.Quotient(), big.NewInt(98))
}

func TestGetInputAmount(t *testing.T) {
pool := newTestPool()

// USDC -> DAI
outputAmount := entities.FromRawAmount(DAI.Currency, big.NewInt(98))
outputAmount := entities.FromRawAmount(DAI, big.NewInt(98))
inputAmount, _, err := pool.GetInputAmount(outputAmount, nil)
if err != nil {
t.Fatal(err)
}
assert.True(t, inputAmount.Currency.Equal(USDC.Currency))
assert.True(t, inputAmount.Currency.Equal(USDC))
assert.Equal(t, inputAmount.Quotient(), big.NewInt(100))

// DAI -> USDC
outputAmount = entities.FromRawAmount(USDC.Currency, big.NewInt(98))
outputAmount = entities.FromRawAmount(USDC, big.NewInt(98))
inputAmount, _, err = pool.GetInputAmount(outputAmount, nil)
if err != nil {
t.Fatal(err)
}
assert.True(t, inputAmount.Currency.Equal(DAI.Currency))
assert.True(t, inputAmount.Currency.Equal(DAI))
assert.Equal(t, inputAmount.Quotient(), big.NewInt(100))
}
19 changes: 9 additions & 10 deletions entities/position.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@ import (
"errors"
"math/big"

"github.com/KyberNetwork/uniswap-sdk-core/entities"

"github.com/KyberNetwork/uniswapv3-sdk/constants"
"github.com/KyberNetwork/uniswapv3-sdk/utils"
"github.com/daoleno/uniswap-sdk-core/entities"
"github.com/daoleno/uniswapv3-sdk/constants"
"github.com/daoleno/uniswapv3-sdk/utils"
)

var (
Expand Down Expand Up @@ -77,15 +76,15 @@ func (p *Position) Amount0() (*entities.CurrencyAmount, error) {
if err != nil {
return nil, err
}
p.token0Amount = entities.FromRawAmount(p.Pool.Token0.Currency, utils.GetAmount0Delta(sqrtTickLower, sqrtTickUpper, p.Liquidity, false))
p.token0Amount = entities.FromRawAmount(p.Pool.Token0, utils.GetAmount0Delta(sqrtTickLower, sqrtTickUpper, p.Liquidity, false))
} else if p.Pool.TickCurrent < p.TickUpper {
sqrtTickUpper, err := utils.GetSqrtRatioAtTick(p.TickUpper)
if err != nil {
return nil, err
}
p.token0Amount = entities.FromRawAmount(p.Pool.Token0.Currency, utils.GetAmount0Delta(p.Pool.SqrtRatioX96, sqrtTickUpper, p.Liquidity, true))
p.token0Amount = entities.FromRawAmount(p.Pool.Token0, utils.GetAmount0Delta(p.Pool.SqrtRatioX96, sqrtTickUpper, p.Liquidity, true))
} else {
p.token0Amount = entities.FromRawAmount(p.Pool.Token0.Currency, constants.Zero)
p.token0Amount = entities.FromRawAmount(p.Pool.Token0, constants.Zero)
}
}
return p.token0Amount, nil
Expand All @@ -95,13 +94,13 @@ func (p *Position) Amount0() (*entities.CurrencyAmount, error) {
func (p *Position) Amount1() (*entities.CurrencyAmount, error) {
if p.token1Amount == nil {
if p.Pool.TickCurrent < p.TickLower {
p.token1Amount = entities.FromRawAmount(p.Pool.Token1.Currency, constants.Zero)
p.token1Amount = entities.FromRawAmount(p.Pool.Token1, constants.Zero)
} else if p.Pool.TickCurrent < p.TickUpper {
sqrtTickLower, err := utils.GetSqrtRatioAtTick(p.TickLower)
if err != nil {
return nil, err
}
p.token1Amount = entities.FromRawAmount(p.Pool.Token1.Currency, utils.GetAmount1Delta(sqrtTickLower, p.Pool.SqrtRatioX96, p.Liquidity, false))
p.token1Amount = entities.FromRawAmount(p.Pool.Token1, utils.GetAmount1Delta(sqrtTickLower, p.Pool.SqrtRatioX96, p.Liquidity, false))
} else {
sqrtTickLower, err := utils.GetSqrtRatioAtTick(p.TickLower)
if err != nil {
Expand All @@ -111,7 +110,7 @@ func (p *Position) Amount1() (*entities.CurrencyAmount, error) {
if err != nil {
return nil, err
}
p.token1Amount = entities.FromRawAmount(p.Pool.Token1.Currency, utils.GetAmount1Delta(sqrtTickLower, sqrtTickUpper, p.Liquidity, false))
p.token1Amount = entities.FromRawAmount(p.Pool.Token1, utils.GetAmount1Delta(sqrtTickLower, sqrtTickUpper, p.Liquidity, false))
}
}
return p.token1Amount, nil
Expand Down
Loading

0 comments on commit bcca8c3

Please sign in to comment.