GithubHelp home page GithubHelp logo

uniswap / v2-sdk Goto Github PK

View Code? Open in Web Editor NEW
421.0 27.0 1.1K 1.26 MB

πŸ›  An SDK for building applications on top of Uniswap V2

Home Page: https://uniswap.org/docs/v2/SDK/getting-started

License: MIT License

TypeScript 100.00%

v2-sdk's Introduction

@uniswap/v2-sdk - Now at Uniswap/sdks

All versions after 4.3.0 of this SDK can be found in the SDK monorepo! Please file all future issues, PR’s, and discussions there.

Old Issues and PR’s

If you have an issue or open PR that is still active on this SDK in this repository, please recreate it in the new repository. Some existing issues and PR’s may be automatically migrated by the Uniswap Labs team.

v2-sdk's People

Contributors

dependabot[bot] avatar jfrankfurt avatar jsy1218 avatar just-toby avatar lint-action avatar marktoda avatar mikeki avatar moodysalem avatar noahzinsmeister avatar willpote 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

v2-sdk's Issues

Waiting for XinFin-XDC Network support in Uniswap

Hello Team,

It will be great if Would you consider to Add ETH compatible DPOS chain (XinFin Network) support in Uniswap.

XinFin Digital Contract or XDC β€” the XinFin network’s native crypto β€” is a one-stop solution that combines speed, scalability, and sustainability into an immaculate package. XDC is built on XinFin’s exclusive consensus mechanism β€” the XinFin Delegated Proof-of-Stake or XDPoS protocol that was specially developed to overcome the shortcomings of the technology that came before it.

XinFin Network: https://xdc.network/home
Github:- https://github.com/XinFinOrg/XDPoSChain
CMC :- https://coinmarketcap.com/currencies/xinfin-network/
Circulating Supply:- https://explorerapi.xinfin.network/publicAPI?module=balance&action=getcirculatingsupply
Total Supply:- https://explorerapi.xinfin.network/publicAPI?module=balance&action=totalXDC
Docker FullNode:- https://github.com/xinfinorg/XinFin-Node
Integration Code example: https://xinfin.org/exchange-listing-resource

Technical Community Support available at:

Telegram Community: https://t.me/XinFinDevelopers
Slack Community: https://xinfin-public.slack.com/messages/CELR2M831/
Slack Invitation Link: https://launchpass.com/xinfin-public
Technical help Resource: http://howto.xinfin.org/

Hope you will revert soon.

tradeEthForExactTokensWithData for last tokens

I'm working on an application that leverages uniswap exchanges. Our ERC20 tokens have 0 decimals. I'm running into an issue when purchasing the last token in the exchange.

When calling tradeEthForExactTokensWithData to purchase the last tokens in an exchange, an error is thrown here https://github.com/Uniswap/uniswap-sdk/blob/1fcc0a59cd960e4ed0465c7714557688c01b31fe/src/computation/trade.ts#L38-L52

Uncaught Error: Passed bigNumber 'Infinity' is not a valid uint256.

This is because denominator becomes 0 and inputAmount is then divided by 0.
https://github.com/Uniswap/uniswap-sdk/blob/1fcc0a59cd960e4ed0465c7714557688c01b31fe/src/computation/trade.ts#L46-L47

Is it possible to support this use case or should the exchange always have remaining tokens in it?

Is seems the js logic mirrors the vyper logic here, although im not sure how vyper handles division by zero.

Retrive the Route for two tokens without a pair

How can i retrive the Route for two tokens that have not a pair ?

The following code uses two tokens that doesn't have a pair on uniswap, and during the execution encouter an error that is reported below. The same code if applied on tokens with a pair works well ( forx example WETH and DAI ) , so i am wondering what i have to change to make this works also with tokens without a pair?

CODE

const { ChainId, Token, TokenAmount, Pair, Route, Fetcher } = require("@uniswap/sdk");

( async () => {
    const AKITA = new Token(
        ChainId.MAINNET,
        "0x3301ee63fb29f863f2333bd4466acb46cd8323e6",
        18
    );
    const SHIBA = new Token(
        ChainId.MAINNET,
        "0xf32aa187d5bc16a2c02a6afb7df1459d0d107574",
        18,
    );
    const pair = await Fetcher.fetchPairData(AKITA, SHIBA);
    const route = new Route([pair], SHIBA)  
    const trade = new Trade(route, new TokenAmount( SHIBA, '1000000000000000000' ), TradeType.EXACT_INPUT)
  
    
    console.log(trade.executionPrice.toSignificant(6))
     
})();

OUTPUT

Warning: 0x3301ee63fb29f863f2333bd4466acb46cd8323e6 is not checksummed.
Warning: 0xf32aa187d5bc16a2c02a6afb7df1459d0d107574 is not checksummed.
(node:138647) UnhandledPromiseRejectionWarning: Error: call revert exception (method="getReserves()", errorArgs=null, errorName=null, errorSignature=null, reason=null, code=CALL_EXCEPTION, version=abi/5.4.1)
    at Logger.makeError (/home/pero/projects/web3-testing/node_modules/@ethersproject/contracts/node_modules/@ethersproject/logger/lib/index.js:199:21)
    at Logger.throwError (/home/pero/projects/web3-testing/node_modules/@ethersproject/contracts/node_modules/@ethersproject/logger/lib/index.js:208:20)
    at Interface.decodeFunctionResult (/home/pero/projects/web3-testing/node_modules/@ethersproject/contracts/node_modules/@ethersproject/abi/lib/interface.js:384:23)
    at Contract.<anonymous> (/home/pero/projects/web3-testing/node_modules/@ethersproject/contracts/lib/index.js:338:56)
    at step (/home/pero/projects/web3-testing/node_modules/@ethersproject/contracts/lib/index.js:48:23)
    at Object.next (/home/pero/projects/web3-testing/node_modules/@ethersproject/contracts/lib/index.js:29:53)
    at fulfilled (/home/pero/projects/web3-testing/node_modules/@ethersproject/contracts/lib/index.js:20:58)
    at process._tickCallback (internal/process/next_tick.js:68:7)
(node:138647) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:138647) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Passed bigNumber is negative for some assets

Hi there! πŸ‘‹

I'm using the latest SDK and getting the following error on some assets:

UnhandledPromiseRejectionWarning: Error: Passed bigNumber '-1.993999755260833107022e+21' is not a valid uint256.
at ensureUInt256 (/PROJECT_DIR/node_modules/@uniswap/sdk/dist/_utils/index.js:31:15)
at Array.forEach ()
at Object.ensureAllUInt256 (/PROJECT_DIR/node_modules/@uniswap/sdk/dist/_utils/index.js:35:16)
at getOutputPrice (/PROJECT_DIR/node_modules/@uniswap/sdk/dist/computation/trade.js:33:14)
at getSingleTradeTransput (/PROJECT_DIR/node_modules/@uniswap/sdk/dist/computation/trade.js:44:11)
at getTradeTransput (/PROJECT_DIR/node_modules/@uniswap/sdk/dist/computation/trade.js:88:29)
at getTradeDetails (/PROJECT_DIR/node_modules/@uniswap/sdk/dist/computation/trade.js:116:14)

Example code:

    let usdc = await getTokenReserves("0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48")
    let marketDetails = getMarketDetails(undefined, usdc)
    let tradeAmount = toWei(2)
    let tradeDetails = getTradeDetails('OUTPUT', tradeAmount, marketDetails)

The same also applies when using the WBTC asset (0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599) for await getTokenReserves().

The code works as expected if OUTPUT is changed to INPUT, or if other assets are used (e.g. DAI - 0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359)

P.S. toWei() is a helper that returns the correct bigNumber needed, so I don't think that is the problem.

Unexpected output amount in getTradeDetails

I'm trying to simulate a trade in order to get the expected output amount (specifically a ETH_TO_TOKEN trade), but the result seems off.
Here I have the full TradeDetails object, for any other question please ask and I'll try to collaborate as best as possible.

{
   "marketDetailsPre":{
      "tradeType":"ETH_TO_TOKEN",
      "inputReserves":{
         "token":{
            "chainId":1,
            "address":"ETH",
            "decimals":18
         }
      },
      "outputReserves":{
         "token":{
            "chainId":1,
            "address":"0xB6eD7644C69416d67B522e20bC294A9a9B405B31",
            "decimals":8
         },
         "exchange":{
            "chainId":1,
            "address":"0x701564Aa6E26816147D4fa211a0779F1B774Bb9B",
            "decimals":18
         },
         "ethReserve":{
            "token":{
               "chainId":1,
               "address":"ETH",
               "decimals":18
            },
            "amount":"32852569879321536723"
         },
         "tokenReserve":{
            "token":{
               "chainId":1,
               "address":"0xB6eD7644C69416d67B522e20bC294A9a9B405B31",
               "decimals":8
            },
            "amount":"4888904204516"
         }
      },
      "marketRate":{
         "rate":"1488.13448155641346731",
         "rateInverted":"0.000671982278748166"
      }
   },
   "marketDetailsPost":{
      "tradeType":"ETH_TO_TOKEN",
      "inputReserves":{
         "token":{
            "chainId":1,
            "address":"ETH",
            "decimals":18
         }
      },
      "outputReserves":{
         "token":{
            "chainId":1,
            "address":"0xB6eD7644C69416d67B522e20bC294A9a9B405B31",
            "decimals":8
         },
         "exchange":{
            "chainId":1,
            "address":"0x701564Aa6E26816147D4fa211a0779F1B774Bb9B",
            "decimals":18
         },
         "ethReserve":{
            "token":{
               "chainId":1,
               "address":"ETH",
               "decimals":18
            },
            "amount":"33852569879321536723"
         },
         "tokenReserve":{
            "token":{
               "chainId":1,
               "address":"0xB6eD7644C69416d67B522e20bC294A9a9B405B31",
               "decimals":8
            },
            "amount":"4744907175624"
         }
      },
      "marketRate":{
         "rate":"1401.638691697191775502",
         "rateInverted":"0.00071345062456084"
      }
   },
   "tradeType":"ETH_TO_TOKEN",
   "tradeExact":"INPUT",
   "inputAmount":{
      "token":{
         "chainId":1,
         "address":"ETH",
         "decimals":18
      },
      "amount":"1000000000000000000"
   },
   "outputAmount":{
      "token":{
         "chainId":1,
         "address":"0xB6eD7644C69416d67B522e20bC294A9a9B405B31",
         "decimals":8
      },
      "amount":"143997028892"
   },
   "executionRate":{
      "rate":"1439.97028892",
      "rateInverted":"0.000694458773000112"
   },
   "marketRateSlippage":"581.236379717223398384",
   "executionRateSlippage":"323.654839218827805522"
}

As you can see, the execution rate is 1439.97028892, so, by giving in 1 ETH, I would expect to get 1 * 1439.97028892 = 1439.97028892 0xBTC out of this. I'm probably doing something wrong here, can you help me?

Freeze while loading datas

Hello, the following code result in a few seconds complete freeze until the result come in which mean that javascript is overloaded and getting totally fucked for a little while, how is that even possible ?)

import { Fetcher, Route } from '@uniswap/sdk'
        const netId = await web3.eth.net.getId();
        const PTE = await Fetcher.fetchTokenData(netId, web3.utils.toChecksumAddress(Env().PEET_CONTRACT_ADDR));
        const USDT = await Fetcher.fetchTokenData(netId, web3.utils.toChecksumAddress(Env().USDT_CONTRACT_ADDR));
        
        const pair = await Fetcher.fetchPairData(PTE, USDT);
        const route = new Route([pair], USDT)

Connect wallet to swap coins.

Hello developer, is there any way to connect wallet with uniswap API so that I can swap coin programatically? looking forward to listen about this.

"use pairAddress to fetch reserves here"

I was looking at the docs

async function getPair(): Promise<Pair> {
  const pairAddress = Pair.getAddress(DAI, WETH[DAI.chainId])

  const reserves = [/* use pairAddress to fetch reserves here */]
  const [reserve0, reserve1] = reserves

  const tokens = [DAI, WETH[DAI.chainId]]
  const [token0, token1] = tokens[0].sortsBefore(tokens[1]) ? tokens : [tokens[1], tokens[0]]

  const pair = new Pair(new TokenAmount(token0, reserve0), new TokenAmount(token1, reserve1))
  return pair
}

Could you be more specific as to how to fetch the reserves? Is this provided by the Uniswap SDK or do we have to use web3?

Example to swap?

A bit disappointed that the docs don't contain an example with an actual swap.

I'm trying to figure it out:

const rpcURL = "https://mainnet.infura.io/v3/...";
const web3 = new Web3(rpcURL);

const contract = new web3.eth.Contract(
    abis.uniswap, // copy pasted from http://api.etherscan.io/api?module=contract&action=getabi&address=0x7a250d5630b4cf539739df2c5dacb4c659f2488d&format=raw
    "0x7a250d5630b4cf539739df2c5dacb4c659f2488d"
);

console.log("methods: " + JSON.stringify(contract.methods));  // {}

Printing the contract shows indeed no methods and events. swapExactETHForTokens appears somewhere in options.jsonInterface. What am I doing wrong?

Providing your own infura api key to the SDK.

Calls to the network with SDK bring up rate limits pretty easily while developing. Is it possible to provide your own infura API key? Looked through the docs and there is no answer regarding that.

TypeError: pairs[0].involvesToken is not a function

I'm getting this error with this code:

`

export const HokkBscPrice = () => {

const BSC_HOKK = new Token(ChainId.MAINNET, "0xe87e15b9c7d989474cb6d8c56b3db4efad5b21e8", 18);

const BSC_PAIR = async () => await Fetcher.fetchPairData(BSC_HOKK, WETH[BSC_HOKK.chainId]);

const BSC_ROUTE = new Route([BSC_PAIR], WETH[BSC_HOKK.chainId]);

return (<>

{BSC_ROUTE.midPrice.toFixed(9)}

</>)

}

export default HokkBscPrice

`

It can be happening maybe because i'm not using typescript but i need a confirmation from you guys, can i?

invalid signer or provider

Hello, I'm trying to use a custom provider, but when I test it always gives me this error:

  reason: 'invalid signer or provider',
  code: 'INVALID_ARGUMENT',
  argument: 'signerOrProvider',
  value: '*my_provedor*'

To clear up the doubt, I tried to use information from Mainnet using infura, but the same error continued.

Can anybody help me?

Code:

var par1 = new sdk_1.Token(1, "0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2", 18);
        var par2 = new sdk_1.Token(1, "0xdac17f958d2ee523a2206206994597c13d831ec7", 6);
        var pair = [await sdk_1.Fetcher.fetchPairData(par1, par2, "xxx")];
        const route = new sdk_1.Route(pair, par2);
        var amountPrecision = Math.round(quant * (10 ** 6));
        const trade = new sdk_1.Trade(route, new sdk_1.TokenAmount(par2, amountPrecision), sdk_1.TradeType.EXACT_INPUT);
        var exec = [trade.executionPrice.toSignificant(6), trade.executionPrice.invert().toSignificant(6)];
        if ((isNaN(exec[0]) || isNaN(exec[1]))) throw 'ERRO 2001';
        return exec;

How can I query my liquidity position?

The Uniswap SDK is not clear about which interface and function to use to query a user's liquidity position such as the one shown by the front-end UI. Attaching a snapshot from the UI showing my liquidity position on the Ropsten network:

Screenshot 2021-09-23 at 17 42 38

Issue with "yarn add @uniswap/sdk"

Hi there, I'm doing some prototyping with a bare bones vite project and the command "yarn add @uniswap/sdk" listed here seems to cause an error when running "yarn dev".

Error Message

[vite] Dep optimization failed with error:
[vite]: Rollup failed to resolve import "@ethersproject/address" from "node_modules/@uniswap/sdk/dist/sdk.esm.js".
This is most likely unintended because it can break your application at runtime.
If you do want to externalize this module explicitly add it to
`rollupInputOptions.external`

Solution
So my solution was to go into package.json and link to this repo directly

 "dependencies": {
    "@uniswap/sdk": "git+https://github.com/Uniswap/uniswap-sdk.git",
    "vue": "^3.0.0-rc.1"
  },

After running yarn install the development sever was able to startup properly.

Steps to reproduce

yarn create vite-app testuniswap
cd testuniswap
yarn
yarn add @uniswap/sdk
yarn dev

How to connect the wallet?

The first step to use these APIs should be to connect the wallet, otherwise how to trade? But I didn't find a way to connect the wallet, thank you.

Call Revert Exeption with Pairs in Testnets

When I try to use the code described here https://uniswap.org/docs/v2/javascript-SDK/fetching-data/ for fetching pair data:

export const getPair = async (
  a: Token,
  b: Token,
  provider: BaseProvider,
): Promise<Pair> => {
  const pairAddress = Pair.getAddress(a, b);

  const pairContract = new ethers.Contract(
    pairAddress,
    pairContractABI,
    provider,
  );

  const reserves = await pairContract.getReserves();

  const [reserve0, reserve1] = reserves;

  const tokens = [a, b];
  const [token0, token1] = tokens[0].sortsBefore(tokens[1])
    ? tokens
    : [tokens[1], tokens[0]];

  const pair = new Pair(
    new TokenAmount(token0, reserve0),
    new TokenAmount(token1, reserve1),
  );

  return pair;
};

I get the following error:

error => Error: call revert exception (method="DOMAIN_SEPARATOR()", errorSignature=null, errorArgs=[null], reason=null, code=CALL_EXCEPTION, version=abi/5.0.10)
    at Logger.makeError (index.ts:205)
    at Logger.throwError (index.ts:217)
    at Interface.decodeFunctionResult (interface.ts:326)
    at Contract.<anonymous> (index.ts:309)
    at Generator.next (<anonymous>)
    at fulfilled (index.ts:2)

The addresses I am using are WETH 0xc778417E063141139Fce010982780140Aa0cD5Ab and DAI 0x5592EC0cfb4dbc12D3aB100b257153436a1f0FEa in RINKEBY

Here's a demo: https://stackblitz.com/edit/typescript-9rjz2m?file=index.ts

Bad Result in outputAmount of Trade TOKEN for TOKEN

When I exchange in TOKEN for WETH or WHET for a TOKEN, the result obtained with trade.outputAmount always gives me the same result as in the uniswap UI.

But when I go to obtain the output price in a TOKEN TRADE for another TOKEN erc-20 I get a different result. Always lower than the one offered by the uniswap UI at the same time.

My code

        const TOKENP = new Token(ChainId.MAINNET, tokenw.hash, tokenw.decimals);
        const TOKEN_M = new Token(ChainId.MAINNET, tokenm.hash, tokenm.decimals); //
        const pair3 = await Fetcher.fetchPairData(TOKEN_M ,TOKEN_P);
        const route3 = new Route([pair3], TOKEN_P);
        let qtyToken = Math.pow(10, 18)*1;
        const tradeM = new Trade(route3, new TokenAmount( TOKEN_P, qtyToken ), TradeType.EXACT_INPUT)
        return tradeM.outputAmount.toSignificant(6); 

Shouldn't this code give me the exact data from the uniswap UI just like it happens to me when I trade with ETH?
This difference increases when the amount of the input token increases. In this case this 1 unit.

nhnhnhnhnhnhnh
nhhnnhnhnhnhnh

If invalid market address is passed, `getTokenReserves` functions fail unexpectedly

The following error happens if I pass a bogus address:

node_1   | (node:1) UnhandledPromiseRejectionWarning: Error: call exception (address="0x42f1E0990beb10FfeE2E884C82a37D425268eD1e", method="decimals()", args=[], version=4.0.45)
node_1   |     at Object.throwError (/root/node_modules/ethers/errors.js:76:17)
node_1   |     at /root/node_modules/ethers/contract.js:182:36
node_1   |     at processTicksAndRejections (internal/process/task_queues.js:93:5)
node_1   | (node:1) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)

getTradeDetails: unexpected executionRate

Hey @NoahZinsmeister - first off, thank you for building this great library.

I'm just digging in & created a few calls based on your Data & Computation examples. I want to confirm I understand the meaning of these outputs.

Here's my script:

const tokenReserves: IUniswapTokenReservesNormalized = await getTokenReserves(
  address, // Dai: '0x89d24A6b4CcB1B6fAA2625fE562bDD9a23260359'
  chainIdOrProvider, // mainnet: 1
);
const marketDetails: IUniswapMarketDetails = getMarketDetails(
  undefined, // undefined === ETH
  tokenReserves,
);
const buyAmount: BigNumber = new BigNumber(amount); // amount: '1'
const tradeAmount: BigNumber = buyAmount.multipliedBy(decimals); // decimals: 18
const tradeDetails: IUniswapTradeDetails = getTradeDetails(
  TRADE_EXACT.OUTPUT,
  tradeAmount,
  marketDetails,
);

When I log out tradeDetails, I get this output (I converted it to JSON). For low buyAmount values (1 in my example), the tradeDetails.executionRate returns some wacky results: 18 in this example, vs. the pre-execution market rate and post-execution market rate of ~215.87. It's only when I increase the buyAmount, e.g. to 1000, does it return an executionRate similar to the market rates (here's my results for 1000).

First, what is the executionRate? I assume it is the actual rate for the trade after accounting for slippage, i.e. my realized rate from executing the given trade? Second, Any idea what's happening here? Perhaps some side effect of turning a small BigNumber into a string? Or is this an actual bug? Even with a small amount of DAI, I'd expect the executionRate to be about the same - even closer to the pre & post market rates.

Let factory address be provided by package consumer

Awesome work on this sdk!

I use it on a local hardhat-deployed uniswap (factory, routerv02, etc). Currently I have to patch the package in order to set a custom factory address.

diff --git a/node_modules/@uniswap/sdk/dist/sdk.cjs.development.js b/node_modules/@uniswap/sdk/dist/sdk.cjs.development.js
index a4450f3..553cfe0 100644
--- a/node_modules/@uniswap/sdk/dist/sdk.cjs.development.js
+++ b/node_modules/@uniswap/sdk/dist/sdk.cjs.development.js
@@ -38,7 +38,7 @@ var _SOLIDITY_TYPE_MAXIMA;
   Rounding[Rounding["ROUND_UP"] = 2] = "ROUND_UP";
 })(exports.Rounding || (exports.Rounding = {}));
 
-var FACTORY_ADDRESS = '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f';
+var FACTORY_ADDRESS = process.env.MODE === 'test' ? '0xe368b31237b833aB46A1B79f06973e383217AbA7' : '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f';
 var INIT_CODE_HASH = '0x96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f';
 var MINIMUM_LIQUIDITY = /*#__PURE__*/JSBI.BigInt(1000); // exports for internal consumption

Would it be possibly to expose the factory address so it can be set to a custom address?

Decimal for every token changes.

I tried your code. For chainlink 18 decimals(like in your code) works. But for usdt 6, for wbtc 5 and so on...

 const usdt= new Token(ChainId.MAINNET, '0xdac17f958d2ee523a2206206994597c13d831ec7', 6, 'USDT', 'Tether USDT');
 const pair = await Fetcher.fetchPairData(usdt, WETH[usdt.chainId]);
 const route = new Route([pair], WETH[usdt.chainId]); //works perfect, but when decimals is 18 it does not.
console.log(route.midPrice.toSignificant(6))

What is the reason for that?

Unable to resolve module 'ws' from @ethersproject

Hi, after installing the Uniswap SDK for a React Native project, it's getting conflicts with ethers library

package.json

"dependencies": {
...
    "@uniswap/sdk": "^3.0.2",
    "ethers": "^5.0.7",
},
"devDependencies": {
...
    "@ethersproject/address": "^5.0.2", // with or without these, still same error
    "@ethersproject/contracts": "^5.0.2",
    "@ethersproject/networks": "^5.0.2",
    "@ethersproject/providers": "^5.0.5",
    "@ethersproject/solidity": "^5.0.2",
}

Screenshot 2020-08-12 at 2 57 29 PM

Any idea what I'm missing here?

Unable to fetch Pair Data uniswap sdk -- React-Native

`import { ethers } from 'ethers';
var uniswap = require(
"@uniswap/sdk"
)
const getTradeDetails = async ( fromAnchor: number ) => {
const ethers = require("ethers")
const HOT = new uniswap.Token(1, "0x4fabb145d64652a948d72533023f6e7a623c7c53", 18);
const NOT = new uniswap.Token(1, "0x6b175474e89094c44da98b954eedeac495271d0f", 18);
console.log("Tokens Created")
const network = ethers.providers.getNetwork(1)
const provider = new ethers.providers.InfuraProvider(ethers.providers.getNetwork(1), "b3ea554a56f24efa8809ce74e075d629");
console.log("PROVIDER CREATED")
let HOT_NOT = null;
try {
HOT_NOT = await uniswap.Fetcher.fetchPairData(HOT, NOT,provider)
console.log("πŸš€ ~ file: index.js ~ line 19 ~ f ~ HOT_NOT", HOT_NOT)
console.log("Pair Data Fetched")

} catch (err) {
    console.log("ERRROR")
    console.log(err.toString())
}

}`

Error:
The error is that it is not returning me the pair data, even though the pair exists, along with the factory that the eth_call is bieng made to the wrong address.

Error: missing revert data in call exception; Transaction reverted without a reason string [ See: https://links.ethers.org/v5-errors-CALL_EXCEPTION ] (data="0x", transaction={"to":"0x66DDD3B7d017A769cC0c702B937c230EBd3c72D6","data":"0x0902f1ac","accessList":null}, error={"reason":"missing response","code":"SERVER_ERROR","requestBody":"{"method":"eth_call","params":[{"to":"0x66ddd3b7d017a769cc0c702b937c230ebd3c72d6","data":"0x0902f1ac"},"latest"],"id":42,"jsonrpc":"2.0"}","requestMethod":"POST","serverError":{},"url":"https://mainnet.infura.io/v3/b3ea554a56f24efa8809ce74e075d629"}, code=CALL_EXCEPTION, version=providers/5.6.8)

Confusion of sdk and v2-sdk

Installing @uniswap/sdk returns a package from "https://github.com/Uniswap/uniswap-sdk.git" - but that URL forwards to this repository, which holds a v1.0.7 version. (not 3.0.3)

Is it now recommended to install @uniswap/v2-sdk ?
Then the docs on uniswap.org (which are also linked in the Readme of this repository) still talk about the old version and should be updated.

"UniswapV2: LOCKED" Error

When calling swapExactTokensForETHSupportingFeeOnTransferTokens on a local fork on Mainnet using Ganache, I'm getting a "UniswapV2: LOCKED" Error.

I suspect this has to do with the new approval process (I'm not sure if it's a new process or just a new UI implementation) where on the UI I would click approve, then swap immediately after instead of waiting for the approve transaction to mine?

If so, any ideas how to call this type of approve using ethers.js or any other suggestions on how to deal with this error and make the swap?

getTokenReserves throw an error for DGD

getTokenReserves('0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A')
throws

Uncaught (in promise) 
Error: call exception 
(address="0xE0B7927c4aF23765Cb51314A0E0521A9645F0E2A", method="decimals()", args=[], version=4.0.32) 
at Object.n [as throwError] (ethers.min.js?e7ea:1) 
at eval (ethers.min.js?e7ea:1)

fetching price from DAI - WETH on rinkeby

Hey, if I want to fetch the price of this pair, I always get this error. Which is not very helpful, in terms of the message.
image
this is the code that I'm using:

      const networkId = this.web3Query.chainId();
      const tokenOne = new Token(networkId, token.address, token.decimal)
      const tokenTwo = new Token(networkId, tokenToCompare.address, tokenToCompare.decimal)
      const pair = await Fetcher.fetchPairData(tokenOne, tokenTwo)
      const route = new Route([pair], tokenTwo)
      console.log(route.midPrice.toSignificant(6))
      console.log(route.midPrice.invert().toSignificant(6))

Am I doing something wrong here?

Is there out-of-the-box possibility to work with another Ethereum network?

Hello,
I'm trying to use this SDK against a product (a fork of Uniswap V2) working with a custom network.
I extended this enum:
const ChainIdPlus = { ...ChainId, NETWORKONE: 101, NETWORKTWO: 102 };
Despite these changes, code is failing in further calls, and so on.

So, the question is there any extensibility out of the box like plugins to be able to work with other networks (a private blockchain, for example) or I have to fork this project and change it appropriately?

TypeError: Cannot set property 'numerator' of undefined

When trying to instantiate a TokenAmount object from the SDK. I keep getting this error. I'm tried every iteration BigInts, Strings, ethers.utils.parseEther...I can figure it out. It's a 'this' that appears to be undefined.

Exception has occurred: TypeError: Cannot set property 'numerator' of undefined at Fraction (/Users/jared/Dev/frontman/node_modules/@uniswap/sdk/dist/sdk.cjs.development.js:454:20) at CurrencyAmount (/Users/jared/Dev/frontman/node_modules/@uniswap/sdk/dist/sdk.cjs.development.js:575:23) at TokenAmount (/Users/jared/Dev/frontman/node_modules/@uniswap/sdk/dist/sdk.cjs.development.js:654:29) at betterSlippage (/Users/jared/Dev/frontman/lib/betterSlippage.js:19:14) at FullTransactionsSubscription.transactionCatcher (/Users/jared/Dev/frontman/index.js:116:20) at FullTransactionsSubscription.emit (/Users/jared/Dev/frontman/node_modules/eventemitter3/index.js:181:35) at AlchemyWebSocketProvider.<anonymous> (/Users/jared/Dev/frontman/node_modules/@alch/alchemy-web3/node_modules/web3-core-subscriptions/dist/web3-core-subscriptions.cjs.js:70:18) at AlchemyWebSocketProvider.emit (/Users/jared/Dev/frontman/node_modules/eventemitter3/index.js:181:35) at AlchemyWebSocketProvider.emitGenericEvent (/Users/jared/Dev/frontman/node_modules/@alch/alchemy-web3/dist/cjs/web3-adapter/webSocketProvider.js:436:14) at SturdyWebSocket.AlchemyWebSocketProvider._this.handleMessage (/Users/jared/Dev/frontman/node_modules/@alch/alchemy-web3/dist/cjs/web3-adapter/webSocketProvider.js:207:27) at SturdyWebSocket.callListener (/Users/jared/Dev/frontman/node_modules/sturdy-websocket/dist/index.js:338:22) at /Users/jared/Dev/frontman/node_modules/sturdy-websocket/dist/index.js:332:61 at Array.forEach (<anonymous>) at SturdyWebSocket.dispatchEventOfType (/Users/jared/Dev/frontman/node_modules/sturdy-websocket/dist/index.js:332:18) at SturdyWebSocket.handleMessage (/Users/jared/Dev/frontman/node_modules/sturdy-websocket/dist/index.js:197:14) at W3CWebSocket.ws.onmessage (/Users/jared/Dev/frontman/node_modules/sturdy-websocket/dist/index.js:150:56) at W3CWebSocket._dispatchEvent [as dispatchEvent] (/Users/jared/Dev/frontman/node_modules/yaeti/lib/EventTarget.js:107:17) at W3CWebSocket.onMessage (/Users/jared/Dev/frontman/node_modules/websocket/lib/W3CWebSocket.js:234:14) at WebSocketConnection.<anonymous> (/Users/jared/Dev/frontman/node_modules/websocket/lib/W3CWebSocket.js:205:19) at WebSocketConnection.emit (events.js:198:13) at WebSocketConnection.processFrame (/Users/jared/Dev/frontman/node_modules/websocket/lib/WebSocketConnection.js:554:26) at /Users/jared/Dev/frontman/node_modules/websocket/lib/WebSocketConnection.js:323:40

getOutputAmount returns wrong calculation result

I create pair with ratio 1200/400 and try to simulate swap.
Input amount is 3 USDC. I add fee for input and expect to get output amount, which should be 1 WETH, but get different value

const USDC = new Token(1, '0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48', 18, 'USDC', 'USD Coin')
const WETH = new Token(1, '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2', 18, 'WETH9', 'Wrapped Ether')
const pair = new Pair(
    CurrencyAmount.fromRawAmount(USDC, 1200 * (10 ** USDC.decimals)),
    CurrencyAmount.fromRawAmount(WETH, 400 * (10 ** WETH.decimals))
);

const imputAmount = CurrencyAmount.fromRawAmount(USDC, 3 * (10 ** USDC.decimals));
const inputAmountWithFee = imputAmount.multiply(new Fraction(1000, 997));
const [outputAmount] = pair.getOutputAmount(inputAmountWithFee);
consoel.log(outputAmount.toSignificant()) // 0.997506

outputAmount should equal to 1, but I get 0.99750
It seems like fee isn't counted correctly

Does it support other Networks and Dex?

I had two questions:

  1. Can this project be used for other Networks such as Polygon?
  2. Can this project be used for other DEX such as Kyberswap, Quickswap,...?

iframe integration doesn't work even on own uniswap site (documentation live example)

iframe integration doesn't work even on own uniswap site, it should show some real live example in documentation page, see link, but it doesn't, and if you check javascript console, there are few errors.. Will it be fixed eventually? and when..?
https://uniswap.org/docs/v2/interface-integration/iframe-integration/#live-example
link above (official example) works only in Firefox. But doesn't work in chrome/safari/opera

Bug when running uniswap-sdk in Macos

Hello,

When running uniswap-sqk in Macos, I got some errors about library.
So I need to install additional libraries:

  • yarn add @ethersproject/providers
  • yarn add @ethersproject/contracts
  • yarn add @ethersproject/solidity

My environment:

  • Macos: 11.0.1
  • Node: v12.16.1
  • yarn: 1.22.4

Custom Provider Error

When calling getTokenReserves with a custom ethers.js provider, we're getting the following errors:

Uncaught (in promise) DOMException: Failed to execute 'postMessage' on 'Window'

add `priceImpact` breakdown

it would be nice to have information on the two contributors to priceImpact: the 0.3% LP fee and x*y=k curve movement.

Query Uniswap markets/exchanges

Is there any way to query the existing markets on Uniswap (i.e. ETH <> ERC20 exchanges)?

It looks like the Uniswap frontend just maintains a hardcoded list?

I took a look at the contracts and the only public method I see is the getExchange on uniswap_factory.vy... I suppose that could be used to query if a given token exchange exists? Any other way to source a list of markets that I'm missing? Thanks!

not valid typescript code

import { ... } from '@uniswap/sdk'

is not valid typescript code, there is no clear example for importing minimal functions or objects for gathering basic data from the sdk

(node:73511) UnhandledPromiseRejectionWarning: Error: failed to meet quorum (method="call", params={"transaction":..

I found a very similar issue like mine. But I cannot find the answer. So I posted a new issue here. Thanks for your help!
#ethers-io/ethers.js#841 (comment)

Part of my code below where @uniswap/sdk used ethers.js with @[email protected] :

require("dotenv").config();
const Web3 = require("web3");
const {
  ChainId,
  Token,
  TokenAmount,
  WETH,
  Fetcher,
  Trade,
} = require("@uniswap/sdk");
const abis = require("./abis");
const Web3WsProvider = require("web3-providers-ws");
const options = {
  timeout: 30000, // ms
  headers: {
    authorization: "Basic username:password",
  },
  clientConfig: {
    maxReceivedFrameSize: 100000000, // bytes - default: 1MiB
    maxReceivedMessageSize: 100000000, // bytes - default: 8MiB
    keepalive: true,
    keepaliveInterval: 60000, // ms
  },

  reconnect: {
    auto: true,
    delay: 5000, // ms
    maxAttempts: 5,
    onTimeout: false,
  },
};

const ws = new Web3WsProvider(
  "wss://mainnet.infura.io/ws/v3/" + process.env.INFURA_URL_0,
  options
);
const web3 = new Web3(ws);

const {address: admin} = web3.eth.accounts.wallet.add(process.env.PRIVATE_KEY);

const init = async () => {

  await web3.eth
    .subscribe("newBlockHeaders")
    .on("data", async (block) => {
      console.log(`New block received. Block # ${block.number}`);

      const dai = new Token(
        ChainId.MAINNET,
        "0x6B175474E89094C44Da98b954EedeAC495271d0F",
        18
      );
      const weth = WETH[dai.chainId];

      const daiWeth_Pair = await Fetcher.fetchPairData(dai, weth);

      const amountsEth = await Promise.all([
        kyber.methods
          .getExpectedRate(
            addresses.tokens.dai,
            "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee",
            AMOUNT_DAI_WEI
          )
          .call(), //! bug possible
        daiWeth_Pair.getOutputAmount(new TokenAmount(dai, AMOUNT_DAI_WEI)),
      ]).catch(console.log);
  }).on("error", (error) => {
      console.log(error);
    });
};

init();

Some Error information:

image

Error1:

New block received. Block # 10929215
New block received. Block # 10929216
(node:73511) UnhandledPromiseRejectionWarning: Error: failed to meet quorum (method="call", params={"transaction":{"to":"0xA478c2975Ab1Ea89e8196811F51A7B7Ade33eB11","data":"0x0902f1ac"},"blockTag":"latest"}, results=[{"weight":1,"start":1601002249658,"result":"0x0000000000000000000000000000000000000000008182938c6e045bed6d6efe00000000000000000000000000000000000000000000604b50e085a4069fac51000000000000000000000000000000000000000000000000000000005f6d5ad5"},{"weight":1,"start":1601002249658,"result":"0x00000000000000000000000000000000000000000081816a72defcb033330d3600000000000000000000000000000000000000000000604c65ac967fa3989342000000000000000000000000000000000000000000000000000000005f6d5b05"},{"weight":1,"start":1601002250409,"result":"0x00000000000000000000000000000000000000000081831f5143b902a9a8e50700000000000000000000000000000000000000000000604b1fdd41a7c07cdd37000000000000000000000000000000000000000000000000000000005f6d5b02"},{"weight":1,"start":1601002250410,"error":{"reason":"missing response","code":"SERVER_ERROR","requestBody":null,"requestMethod":"GET","serverError":{"errno":"ECONNRESET","code":"ECONNRESET","syscall":"read"},"url":"https://api.etherscan.io/api?module=proxy&action=eth_call&to=0xa478c2975ab1ea89e8196811f51a7b7ade33eb11&data=0x0902f1ac&apikey=9D13ZE7XSBTJ94N9BNJ2MA33VMAY2YPIRB"}}], provider={"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":10929215,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":1601002249657,"providerConfigs":[{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":10929215,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":1601002249657,"connection":{"url":"https://mainnet.infura.io/v3/84842078b09946638c03157f83405213"},"_nextId":44,"apiKey":"84842078b09946638c03157f83405213","projectId":"84842078b09946638c03157f83405213","projectSecret":null,"_internalBlockNumber":{},"_fastBlockNumber":10929215,"_fastBlockNumberPromise":{}},"weight":1,"stallTimeout":750,"priority":1},{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":-1024,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":0,"baseUrl":"https://api.etherscan.io","apiKey":"9D13ZE7XSBTJ94N9BNJ2MA33VMAY2YPIRB","_internalBlockNumber":{}},"weight":1,"stallTimeout":750,"priority":1},{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":10929215,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":1601002251606,"connection":{"url":"https://eth-mainnet.alchemyapi.io/v2/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC"},"_nextId":44,"apiKey":"_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC","_internalBlockNumber":{},"_fastBlockNumber":10929215,"_fastBlockNumberPromise":{}},"weight":1,"stallTimeout":750,"priority":1},{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":10929213,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":1601002248720,"connection":{"url":"https://cloudflare-eth.com/"},"_nextId":44,"_internalBlockNumber":{},"fastBlockNumber":10929213,"fastBlockNumberPromise":{}},"weight":1,"stallTimeout":750,"priority":1}],"quorum":2,"highestBlockNumber":10929215,"internalBlockNumber":{},"fastBlockNumber":10929215,"fastBlockNumberPromise":{}}, code=SERVER_ERROR, version=providers/5.0.9)
at Logger.makeError (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/logger/lib/index.js:179:21)
at Logger.throwError (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/logger/lib/index.js:188:20)
at FallbackProvider. (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:676:54)
at step (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:46:23)
at Object.f [as next] (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:27:53)
at fulfilled (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:18:58)
(node:73511) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:73511) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Error2:

(node:73511) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 35)
(node:73511) UnhandledPromiseRejectionWarning: Error: failed to meet quorum (method="getBlockNumber", params={}, results=[{"weight":1,"start":1601003217919,"error":{"reason":"timeout","code":"TIMEOUT","requestBody":"{"method":"eth_getBlockByNumber","params":["latest",false],"id":42,"jsonrpc":"2.0"}","requestMethod":"POST","timeout":120000,"url":"https://cloudflare-eth.com/"}},{"weight":1,"start":1601003217920,"error":{"reason":"timeout","code":"TIMEOUT","requestBody":"{"method":"eth_blockNumber","params":[],"id":42,"jsonrpc":"2.0"}","requestMethod":"POST","timeout":120000,"url":"https://mainnet.infura.io/v3/84842078b09946638c03157f83405213"}},{"weight":1,"start":1601003526002,"error":{"reason":"timeout","code":"TIMEOUT","requestBody":"{"method":"eth_blockNumber","params":[],"id":42,"jsonrpc":"2.0"}","requestMethod":"POST","timeout":120000,"url":"https://eth-mainnet.alchemyapi.io/v2/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC"}},{"weight":1,"start":1601003526002,"error":{"reason":"timeout","code":"TIMEOUT","requestBody":null,"requestMethod":"GET","timeout":120000,"url":"https://api.etherscan.io/api?module=proxy&action=eth_blockNumber&apikey=9D13ZE7XSBTJ94N9BNJ2MA33VMAY2YPIRB"}}], provider={"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":-1024,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":0,"providerConfigs":[{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":-1024,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":0,"connection":{"url":"https://mainnet.infura.io/v3/84842078b09946638c03157f83405213"},"_nextId":43,"apiKey":"84842078b09946638c03157f83405213","projectId":"84842078b09946638c03157f83405213","projectSecret":null,"_internalBlockNumber":{}},"weight":1,"stallTimeout":750,"priority":1},{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":-1024,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":0,"baseUrl":"https://api.etherscan.io","apiKey":"9D13ZE7XSBTJ94N9BNJ2MA33VMAY2YPIRB","_internalBlockNumber":{}},"weight":1,"stallTimeout":750,"priority":1},{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":-1024,"_lastBlockNumber":-2,"_pollingInterval":4000,"_fastQueryDate":0,"connection":{"url":"https://eth-mainnet.alchemyapi.io/v2/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC"},"_nextId":43,"apiKey":"_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC","_internalBlockNumber":{}},"weight":1,"stallTimeout":750,"priority":1},{"provider":{"_isProvider":true,"_events":[],"_emitted":{"block":-2},"formatter":{"formats":{"transaction":{},"transactionRequest":{},"receiptLog":{},"receipt":{},"block":{},"blockWithTransactions":{},"filter":{},"filterLog":{}}},"anyNetwork":false,"_network":{"name":"homestead","chainId":1,"ensAddress":"0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e"},"_maxInternalBlockNumber":-1024,"_lastBlockNumber":-2,"pollingInterval":4000,"fastQueryDate":0,"connection":{"url":"https://cloudflare-eth.com/"},"nextId":43,"internalBlockNumber":{}},"weight":1,"stallTimeout":750,"priority":1}],"quorum":2,"highestBlockNumber":-1,"internalBlockNumber":{}}, code=SERVER_ERROR, version=providers/5.0.9)
at Logger.makeError (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/logger/lib/index.js:179:21)
at Logger.throwError (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/logger/lib/index.js:188:20)
at FallbackProvider. (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:676:54)
at step (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:46:23)
at Object.f [as next] (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:27:53)
at fulfilled (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/providers/lib/fallback-provider.js:18:58)

Error3:

Exception has occurred: Error
Error: missing response (requestBody="{"method":"eth_call","params":[{"to":"0xa478c2975ab1ea89e8196811f51a7b7ade33eb11","data":"0x0902f1ac"},"latest"],"id":43,"jsonrpc":"2.0"}", requestMethod="POST", serverError={"errno":"ECONNRESET","code":"ECONNRESET","syscall":"read"}, url="https://eth-mainnet.alchemyapi.io/v2/_gg7wSSi0KMBsdKnGVfHDueq6xMB9EkC", code=SERVER_ERROR, version=web/5.0.7)
at Logger.makeError (/Users/zheng/Security/bots/ArBot/node_modules/@[email protected]@@ethersproject/logger/lib/index.js:179:21)
at Logger.throwError (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/logger/lib/index.js:188:20)
at /Users/zheng/Security/bots/ArBot/node_modules/@[email protected]@@ethersproject/web/lib/index.js:211:36
at step (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/web/lib/index.js:33:23)
at Object.f [as throw] (/Users/zheng/Security/bots/ArBot/node_modules/@[email protected]@@ethersproject/web/lib/index.js:14:53)
at rejected (/Users/zheng/Security/bots/ArBot/node_modules/
@[email protected]@@ethersproject/web/lib/index.js:6:65)
at process._tickCallback (internal/process/next_tick.js:68:7)

Uniswap JS SDK returns invalid pair address for two ERC20 tokens in hardhat network

I create two ERC20 tokens, deploy them with hardhat on hardhat network, then create Uniswap pair, then retrieve its address with SDK's Fetcher and with my contract. Fetcher returns different address than the one I get in my contract. If I manually substitute the address in sdk.cjs.development.js with the address from the contract, all works, otherwise Fetcher reverts.

So, here is the hardhat script:

const UniswapV2FactoryArtifact = require('@uniswap/v2-core/build/UniswapV2Factory.json');
const UniswapV2Router02Artifact = require('@uniswap/v2-periphery/build/UniswapV2Router02.json');


const moment = require('moment');

const { expect } = require("chai");
const { ethers } = require('hardhat');

// Uniswap sdk
const { Token, Fetcher } = require('@uniswap/sdk')
const hre = require('hardhat');
const chainId = hre.config.networks.hardhat.chainId;


async function testSDK(skillTokenAddress, fakeDAEAddress) {
  const SKILL = await Fetcher.fetchTokenData(chainId, skillTokenAddress,  ethers.provider);
  const FakeDAE = await Fetcher.fetchTokenData(chainId, fakeDAEAddress,  ethers.provider);
  const pair = await Fetcher.fetchPairData(FakeDAE, SKILL, ethers.provider);
  console.log(pair)
}

async function main() {

  const signers = await ethers.getSigners();
  // for (const signer of signers) {
  //   const balance = await signer.getBalance();
  //   console.log(signer.address, ethers.utils.formatUnits(balance))

  // }

  const UniswapV2Factory = await ethers.getContractFactory(
    UniswapV2FactoryArtifact.abi,
    UniswapV2FactoryArtifact.bytecode
  );

  const uniswapV2Factory = await UniswapV2Factory.deploy(signers[0].address);

  const UniswapV2Router02 = await ethers.getContractFactory(
    UniswapV2Router02Artifact.abi,
    UniswapV2Router02Artifact.bytecode
  );
  const uniswapV2Router02 = await UniswapV2Router02.deploy(uniswapV2Factory.address, signers[0].address);
  await uniswapV2Router02.deployed();
  
  const SkillToken = await ethers.getContractFactory('SkillToken');
  const skillToken = await SkillToken.deploy();
  await skillToken.deployed();
  
  const FakeDAE = await ethers.getContractFactory('FakeDAE');
  const fakeDAE = await FakeDAE.deploy();
  await fakeDAE.deployed();
  
  await fakeDAE.approve(uniswapV2Router02.address, 10000);
  await skillToken.approve(uniswapV2Router02.address, 10000);

  console.log(`Skill Address: ${skillToken.address}, FakeDAE address: ${fakeDAE.address}`)

  await expect(uniswapV2Factory.createPair(skillToken.address, fakeDAE.address))
    .to.emit(uniswapV2Factory, "PairCreated"); 

  
  await uniswapV2Router02.addLiquidity(
    skillToken.address, 
    fakeDAE.address,
    8000,
    8000,
    7999,
    7999,
    signers[0].address,
    moment().add(10, 'seconds').unix()
  );

  await uniswapV2Router02.swapTokensForExactTokens(
    1,
    2,
    [fakeDAE.address, skillToken.address],
    signers[0].address,
    moment().add(1, 'minutes').unix()
  );

  const LiqCalc = await ethers.getContractFactory('LiqCalc');
  const liqCalc = await LiqCalc.deploy(uniswapV2Factory.address);
  await liqCalc.deployed();
  const info = await liqCalc.pairInfo(skillToken.address, fakeDAE.address);
  console.log(info)
  
  await testSDK(skillToken.address, fakeDAE.address);



  
}

main()
  .then(() => process.exit(0))
  .catch(error => {
    console.error(error);
    process.exit(1);
  });

We deployed two ERC20 tokens, Skill and FakeDAE:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/access/AccessControl.sol";

// for debug
import "hardhat/console.sol";


contract SkillToken is ERC20, AccessControl {
  uint public INITIAL_SUPPLY = 12000;
  bytes32 public constant BURNER_ROLE = keccak256("BURNER_ROLE");

  function decimals() public view override returns (uint8) {
    console.log('Skill token decimals');
    return 18;
  }

  constructor() ERC20("SkillToken", "SKILL") {
    _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
    _mint(_msgSender(), INITIAL_SUPPLY);
  }

  function burn(address from, uint256 amount) public {
    require(hasRole(BURNER_ROLE, _msgSender()), "Caller is not a burner");
    _burn(from, amount);
  }

}

and FakeDAE is analogeous.

LiqCal is a contract which reports the valid pair address:

//SPDX-License-Identifier: Unlicense

pragma solidity ^0.6.6;

import '@uniswap/v2-periphery/contracts/libraries/UniswapV2Library.sol';
import '@uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol';

import "hardhat/console.sol";


contract LiqCalc  {
    address public factory;
    constructor(address factory_) public {
        factory = factory_;
    }

    function pairInfo(address tokenA, address tokenB) public view returns (uint reserveA, uint reserveB, uint totalSupply) {
        IUniswapV2Pair pair = IUniswapV2Pair(UniswapV2Library.pairFor(factory, tokenA, tokenB));
        console.log('LiqCal, pair addr:', address(pair));
        totalSupply = pair.totalSupply();
        (uint reserves0, uint reserves1,) = pair.getReserves();
        (reserveA, reserveB) = tokenA == pair.token0() ? (reserves0, reserves1) : (reserves1, reserves0);
    }
 
}

which is 0x21e7b0ced250469051a249252a33c7c5eb13a1f6

However, Fetcher returns invalid pair:

Fetcher.fetchPairData = function fetchPairData(tokenA, tokenB, provider) {
    console.log(`====> chainA=${tokenA.chainId}, addrA: ${tokenA.address}, chainB =${tokenB.chainId}, addrB: ${tokenB.address}`)
    try {
      console.log(`typeof provider: ${typeof provider}`)
      if (provider === undefined) provider = providers.getDefaultProvider(networks.getNetwork(tokenA.chainId));
      !(tokenA.chainId === tokenB.chainId) ? "development" !== "production" ? invariant(false, 'CHAIN_ID') : invariant(false) : void 0;
      var address = Pair.getAddress(tokenA, tokenB);
      console.log(`Pair address in Fetcher: ${address}, substituted: 0x21e7b0ced250469051a249252a33c7c5eb13a1f6`)

      address = '0x21e7b0ced250469051a249252a33c7c5eb13a1f6';
      return Promise.resolve(new contracts.Contract(address, IUniswapV2Pair.abi, provider).getReserves()).then(function (_ref) {
        var reserves0 = _ref[0],
            reserves1 = _ref[1];
        var balances = tokenA.sortsBefore(tokenB) ? [reserves0, reserves1] : [reserves1, reserves0];
        return new Pair(new TokenAmount(tokenA, balances[0]), new TokenAmount(tokenB, balances[1]));
      });
    } catch (e) {
      return Promise.reject(e);
    }
  };

from console.log:

Pair address in Fetcher: 0x7818b27560325CD29600237a5a14880b6f392Ea8, substituted: 0x21e7b0ced250469051a249252a33c7c5eb13a1f6

When I don't not substitute inside Fetcher my pair, getReserves() reverts obviously, because no such pair exists.

The entire log from the run with substituted pair address (all works):

npx hardhat run scripts/uniswap-script.js 
Skill Address: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0, FakeDAE address: 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
LiqCal, pair addr: 0x21e7b0ced250469051a249252a33c7c5eb13a1f6
[
  BigNumber { _hex: '0x1f3f', _isBigNumber: true },
  BigNumber { _hex: '0x1f42', _isBigNumber: true },
  BigNumber { _hex: '0x1f40', _isBigNumber: true },
  reserveA: BigNumber { _hex: '0x1f3f', _isBigNumber: true },
  reserveB: BigNumber { _hex: '0x1f42', _isBigNumber: true },
  totalSupply: BigNumber { _hex: '0x1f40', _isBigNumber: true }
]
Skill token decimals
Fake token decmals
====> chainA=31337, addrA: 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9, chainB =31337, addrB: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
typeof provider: object
Calling Pair get address for A: 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9, B: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0
Pair address in Fetcher: 0x7818b27560325CD29600237a5a14880b6f392Ea8, substituted: 0x21e7b0ced250469051a249252a33c7c5eb13a1f6
Calling Pair get address for A: 0x9fE46736679d2D9a65F0992F2272dE9f3c7fa6e0, B: 0xCf7Ed3AccA5a467e9e704C703E8D87F634fB0Fc9
Pair {
  liquidityToken: Token {
    decimals: 18,
    symbol: 'UNI-V2',
    name: 'Uniswap V2',
    chainId: 31337,
    address: '0x7818b27560325CD29600237a5a14880b6f392Ea8'
  },
  tokenAmounts: [
    TokenAmount {
      numerator: [JSBI],
      denominator: [JSBI],
      currency: [Token],
      token: [Token]
    },
    TokenAmount {
      numerator: [JSBI],
      denominator: [JSBI],
      currency: [Token],
      token: [Token]
    }
  ]
}

What am I doing incorrect?

ES6/Browser consumption?

Hi anyway I can compile the files for using in browser? With TypeScript if possible but I am okay with a JS file without typing. I tried compiling them using TypeScript myself but was unsuccessful because of import statements like these

import JSBI from 'jsbi';
export { default as JSBI } from 'jsbi';
import invariant from 'tiny-invariant';
...

Error: Cannot find module '@ethersproject/address'

Steps to reproduce

npm i @uniswap/sdk

In my Index.js file

const UNISWAP = require('@uniswap/sdk') console.log(The chainId of mainnet is ${UNISWAP.ChainId.MAINNET}.)

Error:
`$ node index.js
internal/modules/cjs/loader.js:968
throw err;
^

Error: Cannot find module '@ethersproject/address'
Require stack:

  • C:\Users\ROUT SAINGYUKTA\Documents\Uniswap\node_modules@uniswap\sdk\dist\sdk.cjs.development.js
  • C:\Users\ROUT SAINGYUKTA\Documents\Uniswap\node_modules@uniswap\sdk\dist\index.js
  • C:\Users\ROUT SAINGYUKTA\Documents\Uniswap\index.js
    ←[90m at Function.Module._resolveFilename (internal/modules/cjs/loader.js:965:15)←[39m
    ←[90m at Function.Module._load (internal/modules/cjs/loader.js:841:27)←[39m
    ←[90m at Module.require (internal/modules/cjs/loader.js:1025:19)←[39m
    ←[90m at require (internal/modules/cjs/helpers.js:72:18)←[39m
    at Object. (C:\Users\ROUT SAINGYUKTA\Documents\Uniswap\node_modules\←[4m@uniswap←[24m\sdk\dist\sdk.cjs.development.js:10:15)
    ←[90m at Module._compile (internal/modules/cjs/loader.js:1137:30)←[39m
    ←[90m at Object.Module._extensions..js (internal/modules/cjs/loader.js:1157:10)←[39m
    ←[90m at Module.load (internal/modules/cjs/loader.js:985:32)←[39m
    ←[90m at Function.Module._load (internal/modules/cjs/loader.js:878:14)←[39m
    ←[90m at Module.require (internal/modules/cjs/loader.js:1025:19)←[39m {
    code: ←[32m'MODULE_NOT_FOUND'←[39m,
    requireStack: [
    ←[32m'C:\Users\ROUT SAINGYUKTA\Documents\Uniswap\node_modules\@Uniswap\sdk\dist\sdk.cjs.development.js'←[39m,
    ←[32m'C:\Users\ROUT SAINGYUKTA\Documents\Uniswap\node_modules\@Uniswap\sdk\dist\index.js'←[39m,
    ←[32m'C:\Users\ROUT SAINGYUKTA\Documents\Uniswap\index.js'←[39m
    ]
    }`

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.