Git Product home page Git Product logo

uniswapv3-sdk's Introduction

Uniswap V3 SDK

API Reference Test Go Report Card

🛠 A Go SDK for building applications on top of Uniswap V3

Installation

go get github.com/daoleno/uniswapv3-sdk

Usage

The following example shows how to create a pool, and get the inputAmount

package main

import (
	"fmt"
	"math/big"

	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"
)

var (
	USDC     = core.NewToken(1, common.HexToAddress("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"), 6, "USDC", "USD Coin")
	DAI      = core.NewToken(1, common.HexToAddress("0x6B175474E89094C44Da98b954EedeAC495271d0F"), 18, "DAI", "Dai Stablecoin")
	OneEther = big.NewInt(1e18)
)

func main() {
	// create demo ticks
	ticks := []entities.Tick{
		{
			Index:          entities.NearestUsableTick(utils.MinTick, constants.TickSpacings[constants.FeeLow]),
			LiquidityNet:   OneEther,
			LiquidityGross: OneEther,
		},
		{
			Index:          entities.NearestUsableTick(utils.MaxTick, constants.TickSpacings[constants.FeeLow]),
			LiquidityNet:   new(big.Int).Mul(OneEther, constants.NegativeOne),
			LiquidityGross: OneEther,
		},
	}

	// create tick data provider
	p, err := entities.NewTickListDataProvider(ticks, constants.TickSpacings[constants.FeeLow])
	if err != nil {
		panic(err)
	}

	// new pool
	pool, err := entities.NewPool(USDC, DAI, constants.FeeLow, utils.EncodeSqrtRatioX96(constants.One, constants.One), OneEther, 0, p)
	if err != nil {
		panic(err)
	}

	// USDC -> DAI
	outputAmount := core.FromRawAmount(DAI, big.NewInt(98))
	inputAmount, _, err := pool.GetInputAmount(outputAmount, nil)
	if err != nil {
		panic(err)
	}
	fmt.Println(inputAmount.ToSignificant(4))
}

More Examples

uniswapv3-sdk's People

Contributors

0xanarz avatar achiko avatar daoleno avatar leyafo avatar n8wb avatar vaulverin avatar xiang-xx avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

uniswapv3-sdk's Issues

How to use auto permit(allowance) when operating the position?

Hi, guys. Thanks for sharing this SDK.

I have a question about auto perimting allowance when calling mutilcall. I saw two parameters (Token0Permit, Token1Permit) in CommonAddLiquidityOptions:

//  Options for producing the calldata to add liquidity
type CommonAddLiquidityOptions struct {
	SlippageTolerance *core.Percent  // How much the pool price is allowed to move
	Deadline          *big.Int       // When the transaction expires, in epoch seconds
	UseNative         *core.Ether    // Whether to spend ether. If true, one of the pool tokens must be WETH, by default false
	Token0Permit      *PermitOptions // The optional permit parameters for spending token0
	Token1Permit      *PermitOptions // The optional permit parameters for spending token1
}

These two permit parameters defined in https://github.com/daoleno/uniswapv3-sdk/blob/master/periphery/selfpermit.go

I know it would be wrapped in AddCallParameters automatically. But I don't know how to wrap the VRS(signature data).
Can you give me a simple example for calling AddCallParameters with perimited parameters?

Token has no field or method Currency

github.com/daoleno/uniswapv3-sdk v0.3.0

DAI.Currency undefined (type *"github.com/daoleno/uniswap-sdk-core/entities".Token has no field or method Currency)

fund disappeard after traded from USDT to ETH

Hello, @daoleno, I follow your code to trade from USDT TO ETH, here is my code

  • s.backedn is *ethclient.Client
  • s.tokenOut is *coreEntities.Token of USDT
  • s.tokenIn is *coreEntities.Token of WETH
pool, err := helper.ConstructV3Pool(s.backend, s.tokenOut, s.tokenIn, uint64(constants.FeeLow))
	if err != nil {
		return err
	}
	//0.1%
	slippageTolerance := coreEntities.NewPercent(big.NewInt(10), big.NewInt(1000))
	//after 5 minutes
	d := time.Now().Add(time.Minute * time.Duration(5)).Unix()
	deadline := big.NewInt(d)

	// single trade input
	// single-hop exact input
	r, err := entities.NewRoute([]*entities.Pool{pool}, s.tokenOut, s.tokenIn)
	if err != nil {
		return err
	}

	swapValue := helper.FloatStringToBigInt(spentValue, int(s.tokenOut.Decimals()))
	trade, err := entities.FromRoute(r, coreEntities.FromRawAmount(s.tokenOut, swapValue), coreEntities.ExactInput)
	if err != nil {
		return err
	}
	log.Printf("%v %v\n", trade.Swaps[0].InputAmount.Quotient(), trade.Swaps[0].OutputAmount.Quotient())
	params, err := periphery.SwapCallParameters([]*entities.Trade{trade}, &periphery.SwapOptions{
		SlippageTolerance: slippageTolerance,
		Recipient:         s.wallet.PublicKey,
		Deadline:          deadline,
	})
	if err != nil {
		return err
	}
	log.Printf("calldata = 0x%x\n", params.Value.String())

	tx, err := helper.SendTX(s.backend, common.HexToAddress(helper.ContractV3SwapRouterV1),
		params.Value, params.Calldata, s.wallet)
	if err != nil {
		return err
	}
	log.Println(tx.Hash().String())
	// t, isPending, err := s.backend.TransactionByHash(context.Background(), tx.Hash())
	return nil

transaction can be sent, but token is lost.

you can check transaction on the link below

0x996bdd1caf45696f4ab85c767b4b3306ea96b737a623d1bf30a5bf4f9c93dce1

Please help me, Thanks you very much.

"invalid tick index" incorrect check

https://github.com/daoleno/uniswapv3-sdk/blob/master/entities/ticklist.go#L60-L62

func GetTick(ticks []Tick, index int) Tick {
	tick := ticks[binarySearch(ticks, index)]
	if tick.Index <= 0 {
		panic("invalid tick index")
	}
	return tick
}

Hi @daoleno ,

I think this function should be something like

func GetTick(ticks []Tick, index int) Tick {
        tickIndex := binarySearch(ticks, index)
        if tickIndex < 0 {
		panic("invalid tick index")
	}
	tick := ticks[tickIndex]

	return tick
}

Because tick.Index can be negative. Am I right?

How does swap provide a pool with the correct output state?

pool, err := NewPool(p.Token0, p.Token1, p.Fee, sqrtRatioX96, liquidity, tickCurrent, p.TickDataProvider)

I don't understand how this is returning the correct new pool state because it just changes the tick and the price, but it doesn't actually update the tick liquidity from the tick data provider.

Am I missing something here?
If the tick liquidity isn't added or subtracted, then the liquidityNet for the consumed ticks isn't correct for pricing the next swap.

Output amount is not calculated correctly in some cases

Hi guys, first of all, thank you for the great library and the effort to maintain it!

Issue:

in some cases pool.GetOutputAmount() (and Pool.swap() ) is not calculating output amount correctly with ExactInput option

Suspected case:

when current tick of the pool is negative

How to reproduce:

try to form a swap tx for UNI/WETH/30 pool with exact input WETH amount (0.1 in my case). Current tick for the pool is something close to -55200.
Check the value returned from pool.GetOutputAmount() (called from FromRoute(...,coreEntities.ExactInput) ) .

abi can not pack (Standard)PermitArguments

abi: cannot use uint as type uint8 as argument
when calling abi.Pack("selfPermit", token.Address, options.Amount, options.Deadline, options.V, options.R, options.S) in selfpermit.go

examples->swap error: "tick net delta must be zero"

Hi,bro:
I used the swap operation, ValidateList method is error, and I looked at the assignment in the ticks:

ticks := []entities.Tick{
  {
	  Index: entities.NearestUsableTick(sdkutils.MinTick,
		  constants.TickSpacings[feeAmount]),
	  LiquidityNet:   pooltick.LiquidityNet,
	  LiquidityGross: pooltick.LiquidityGross,
  },
  {
	  Index: entities.NearestUsableTick(sdkutils.MaxTick,
		  constants.TickSpacings[feeAmount]),
	  LiquidityNet:   pooltick.LiquidityNet,
	  LiquidityGross: pooltick.LiquidityGross,
  },
}

this ticks LiquidityNet value inside is exactly the same,ValidateList:

sum := big.NewInt(0)
for _, tick := range ticks {
  sum.Add(sum, tick.LiquidityNet)
}
if sum.Cmp(big.NewInt(0)) != 0 {
  return ErrZeroNet
}

so the result always ErrZeroNet, Help to see if there is a problem her,thanks!

SwapCallParameters function problem

Hi, I have a problem for swapping tokens
this is my code

import (
	"math/big"
	"time"

	"log"

	coreEntities "github.com/daoleno/uniswap-sdk-core/entities"
	"github.com/daoleno/uniswapv3-sdk/constants"
	"github.com/daoleno/uniswapv3-sdk/entities"
	"github.com/daoleno/uniswapv3-sdk/examples/helper"
	"github.com/daoleno/uniswapv3-sdk/periphery"
	"github.com/ethereum/go-ethereum/common"
	"github.com/ethereum/go-ethereum/ethclient"
)

var ETHRPC = "https://kovan.infura.io/v3/{{id}}"

func main() {
	client, err := ethclient.Dial(ETHRPC)
	if err != nil {
		log.Fatal(err)
	}
	wallet := helper.InitWallet({prv_key})
	if wallet == nil {
		log.Fatal("init wallet failed")
	}

	usdt := coreEntities.NewToken(42, common.HexToAddress("0x07de306ff27a2b630b1141956844eb1552b956b5"), 6, "USDT", "Tether USD")
	weth := coreEntities.NewToken(42, common.HexToAddress("0xd0a1e359811322d97991e03f863a0c30c2cf029c"), 18, "WETH", "Wrapped Ether")

	pool, err := helper.ConstructV3Pool(client, usdt, weth, uint64(constants.FeeMedium))
	if err != nil {
		log.Fatal(err)
	}

	//0.01%
	slippageTolerance := coreEntities.NewPercent(big.NewInt(1), big.NewInt(1000))
	//after 5 minutes
	d := time.Now().Add(time.Minute * time.Duration(15)).Unix()
	deadline := big.NewInt(d)

	// single trade input
	// single-hop exact input
	r, err := entities.NewRoute([]*entities.Pool{pool}, usdt, weth)
	if err != nil {
		log.Fatal(err)
	}

	swapValue := helper.FloatStringToBigInt("2", 6)
	trade, err := entities.FromRoute(r, coreEntities.FromRawAmount(usdt, swapValue), coreEntities.ExactInput)
	if err != nil {
		log.Fatal(err)
	}

	log.Printf("%v %v\n", trade.Swaps[0].InputAmount.Quotient(), trade.Swaps[0].OutputAmount.Wrapped().Quotient())
	params, err := periphery.SwapCallParameters([]*entities.Trade{trade}, &periphery.SwapOptions{
		SlippageTolerance: slippageTolerance,
		Recipient:         wallet.PublicKey,
		Deadline:          deadline,
	})
	if err != nil {
		log.Fatal(err)
	}

	to := common.HexToAddress("0x68b3465833fb72a70ecdf485e0e4c7bd8665fc45")

	tx, err := helper.TryTX(client, to,
		big.NewInt(0), params.Calldata, wallet)
	if err != nil {
		log.Fatal(err)
	}
	log.Println(tx.Hash().String())

}

and it returns me The execution failed due to an exception. this error.
so I searched about this error and understood that one of the main reasons is corrupted input data
so instead of using SwapCallParameters I swapped with uniswap web application and extracted its input data https://kovan.etherscan.io/tx/0xd9ba16700e54348c0e9648e4eeec7160ec523a92bff8baca237687ea86a5300c
and used it in code and it generate this transaction successfully https://kovan.etherscan.io/tx/0x360d93ba9ba7f39acf5ae7931528e4ecb8666fc6fe1b4213e513abea826571af
so I think maybe there is a problem with this function but I can't debug it
i appreciate any help

ConstructV3Pool failing for a live pool

Hey, I was trying to use your package to interact with a pool on maiinet but I get an error when using ConstructV3Pool

        unipool = "0x82c427AdFDf2d245Ec51D8046b41c4ee87F0d29C"
        weth    = "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2"
        osqth   = "0xf1B99e3E573A1a9C5E6B2Ce818b617F0E664E86B"
        chainID, _ := client.ChainID(context.Background())
	c := uint(chainID.Uint64())
	token0 := coreEntities.NewToken(c, common.HexToAddress(weth), 18, "WETH", "weth")
	token1 := coreEntities.NewToken(c, common.HexToAddress(osqth), 18, "oSQTH", "opyn squeeth")
	//amountIn := helper.FloatStringToBigInt("1.00", 18)
	pool, err := ConstructV3Pool(client, token0, token1, uint64(constants.FeeMedium))
	if err != nil {
		log.Fatal(err)
	}

I get the following error tick net delta must be zero , which as I understand is something about validating the ticks in ValidateList. But I don't know enough of the details of uniswap to understand how to fix this or why this pool fails.

Do you have an idea?
etherscan link of the pool: https://etherscan.io/address/0x82c427adfdf2d245ec51d8046b41c4ee87f0d29c#readContract

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.