Git Product home page Git Product logo

v2-periphery's Introduction

Uniswap V2

Actions Status npm

In-depth documentation on Uniswap V2 is available at uniswap.org.

The built contract artifacts can be browsed via unpkg.com.

Local Development

The following assumes the use of node@>=10.

Install Dependencies

yarn

Compile Contracts

yarn compile

Run Tests

yarn test

v2-periphery's People

Contributors

dependabot[bot] avatar haydenadams avatar k06a avatar marktoda avatar moodysalem avatar noahzinsmeister 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  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-periphery's Issues

Tag a release?

I noticed that uniswap-v2-core has non-beta tags, but this project's only tag is 1.0.0-beta.0. Should there be a non-beta tag here?

Side note: what tags match what is currently deployed on mainnet? That's what I want to be sure I'm using

how to calculate the pairFor init code hash

how to calculate the pairFor init code hash? can you give a js example?

function pairFor(address factory, address tokenA, address tokenB) internal pure returns (address pair) {
    (address token0, address token1) = sortTokens(tokenA, tokenB);
    pair = address(uint(keccak256(abi.encodePacked(
            hex'ff',
            factory,
            keccak256(abi.encodePacked(token0, token1)),
            hex'edf6876fa96311f9614f5d804cb3fd74f32d2ce90ea1b2ee31bae1b1a6118ac0' // init code hash
        ))));
}

swapExactTokensForTokensSupportingFeeOnTransferTokens should return uint[] memory amounts

swapExactTokensForTokensSupportingFeeOnTransferTokens is supposed to be identical to swapExactTokensForTokens with the only difference being it doesn'f fail for tokens that take a fee on transaction, therefore, could anyone explain why it doesn't return uint[] memory amounts it is important to me to programmatically obtain (in the simplier possible way) the amount of token(s) received.

I think this is a bug or mistake from UniSwap, could anyone confirm?

#92

Thanks,
aress31

revert action requires an active reserve

i am doing a flashswap and i have this error that idont know where it come from , i spent already 10 das on this with no clue,
" VM Exception while processing transaction: revert Action requires an active reserve "
, it reverts after leaving uniswapv2call, i checked all the params inside it and everthing is fine, i use getamountsin() to repay the loan wuth second token, in this case weth.

UniswapV2Library pairFor() returns wrong address

Hello, when working to integrate my project with Uniswap I ran into some trouble when interacting with the UniswapVRouter02 contract. Whenever I would attempt to add liquidity to a uniswap pair the transaction would always revert.

I investigated further and detirmined that the cause of this was that the pairFor function in UniswapV2Library.sol was returning the wrong address value. It should be noted that this I had this error while using both a private ethereum network running on geth and while testing using ganache-cli. I must admit that I am not a master of the inner workings of the EVM. I do not claim to know the reasoning for the code on line 20 of UniswapV2Library.sol that assigns the return value. Though when I changed it to fetch the address from the uniswapV2factory itself this problem was solved. I believe that there is likely some reason that I don't understand as to why this is not a problem on the mainnet or the other public testnets because uniswap seems to not have this trouble on those networks.

Steps to reproduce:

git clone https://github.com/MaxFeldman1/reproduceError.git
cd reproduceError/uniswap-v2-periphery
npm i @uniswap/lib
npm i @uniswap/v2-core
truffle build
cd ../uniswap-v2-core
truffle build
#copy UniswapV2Router02 artifact to uniswap-v2-core
cp ../uniswap-v2-periphery/build/contracts/UniswapV2Router02.json ./build/contracts
#at this point you would like to spin up a local eth network such as ganache-cli
#be sure to add the tag --allowUnlimitedContractSize if you are using ganache-cli 
#or other tag suitable to your specific local eth instance as the UniswapV2Router bytesize will be over 24kb
#also make sure to NOT add the quiet tag to your eth instance

truffle test
#you can expect that the 'before each' test will pass before the 'adds liquidity' test fails
#find the hash of the most recent transaction in your local eth instance it should have reverted
#also make mental note of the address of the pair created you can find this in the events section underneath the failed test
#to debug the transaction we need to go back into the periphery contracts directory
cd ../uniswap-v2-periphery
truffle debug  #put transaction hash here
#place a break on UniswapV2Library.sol:26
b UniswapV2Library.sol:26
#I intentionally added line 26 to say 'return pair;' which has no effect other than  
#that while debugging you have the opportunity to find the returned value of the pairFor function before the transaction reverts
#to find the value enter the following
:pair
#if you compare this to the value shown in the pair created event there is a definite difference
#if you step through the few steps that are left in the transaction 
#it is apparent that this is the cause of the failure of the transaction

It should be noted that the only line I changed was line 21 of UniswapV2Library.sol and that was only for purposes of debugging the transaction. The transaction will still revert if this line is removed.

I should also alert you to the fact that this problem still occurs when instead of getting the artifact for UniswapV2Router02 locally I use the one linked to on github by Uniswap at unpkg.com though due to lack of original source code the latter artifact makes debugging cumbersome.

####$ truffle version
Truffle v5.1.24 (core: 5.1.24)
Solidity - 0.5.16 (solc-js) #when in uniswap-v2-core
Solidity - 0.6.6 (solc-js) #when in uniswap-v2-periphery
Node v12.16.2
Web3.js v1.2.1

I have used multiple eth instances so I do not believe this is the root of the problem though if you find it relevant the information is below

$ganache-cli --version
Ganache CLI v6.9.1 (ganache-core: 2.10.2)

$geth version
Geth
Version: 1.9.13-stable
Git Commit: cbc4ac264e9671898bff6ec7e434da3eca4bd273
Architecture: amd64
Protocol Versions: [65 64 63]
Go Version: go1.14.2
Operating System: linux

Can't remove liquidity for ETH-UDOO Pair

Transaction is successfully sent, but liquidity is not removed.

Here I attach:
remove liquidity sent

1 - Screenshot of confirmation (remove_liquidity_sent.png)
2 - Wallet Address (Argent wallet running on iOS): 0x652164D5FD53D1f7eaE245FF9545cC9F4888A400
3 - Transaction ID: 0x6b525d073b6f8bd1549f439617b23605ff8f27eb9834ed7e939d3e01ede86c12
4 - Token Address (Current): 0x12f649a9e821f90bb143089a6e56846945892ffb

Thanks in advance uniswap team!
Your app is AWESOME

Maybe there is a little error in UniswapV2LiquidityMathLibrary.sol

it appears in function computeProfitMaximizingTrade {}

uint256 leftSide = Babylonian.sqrt( FullMath.mulDiv( invariant.mul(1000), aToB ? truePriceTokenA : truePriceTokenB, (aToB ? truePriceTokenB : truePriceTokenA).mul(997) )

I think the leftSide should be this:
uint256 leftSide = Babylonian.sqrt( FullMath.mulDiv( invariant.mul(1000**2), aToB ? truePriceTokenA : truePriceTokenB, (aToB ? truePriceTokenB : truePriceTokenA).mul(997**2) )

Thinks in advance!

Can't call UniswapRouterV2.swapExactTokensForTokens from another contract

I'm trying to integrate Uniswap into my own contract, I have given the UniswapRouterV2 contract allowance to transfer tokens on my behalf but still I'm getting TRANSFER_FROM_FAILED. I have been testing in Ropsten. The weird stuff is that calling the router contract directly (from Etherscan for example) with the exact same parameters does not fail at all and correctly swaps the token and deposits the target token in the target account.

I'm posting here my contract code, is a really simple Test contract.

pragma solidity ^0.8.1;
pragma experimental ABIEncoderV2;

import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-core/contracts/interfaces/IUniswapV2Factory.sol";

contract PaymentGateway {
    address internal constant UNISWAP_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D;
    address internal constant UNISWAP_FACTORY_ADDRESS = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;

    IUniswapV2Router02 public uniswapRouter;
    IUniswapV2Factory public uniswapFactory;


    constructor() {
        uniswapRouter = IUniswapV2Router02(UNISWAP_ROUTER_ADDRESS);
        uniswapFactory = IUniswapV2Factory(UNISWAP_FACTORY_ADDRESS);
    }

    function swapTokensForExactTokens(
        uint _amount,
        uint  _min,
        address _sourceToken,
        address _targetToken,
        address _recipient,
        uint  _deadline
    ) external returns (uint[] memory) {
        address[] memory path = new address[](2);
        path[0] = _sourceToken;
        path[1] = _targetToken;

        uint[] memory amounts = uniswapRouter.swapTokensForExactTokens(
            _amount,
            _min,
            path,
            _recipient,
            _deadline
        );

        return amounts;
    }

    function swapExactTokensForTokens(
        uint _amount,
        uint _min,
        address _sourceToken,
        address _targetToken,
        address _recipient,
        uint _deadline
    ) external returns (uint[] memory) {
        address[] memory path = new address[](2);
        path[0] = _sourceToken;
        path[1] = _targetToken;

        uint[] memory amounts = uniswapRouter.swapExactTokensForTokens(
            _amount,
            _min,
            path,
            _recipient, 
            _deadline
        );

        return amounts;
    }
}

Has anyone experienced something similar?

Thanks in advance

failed to call addLiquidity on the rinkeby testnet using remix IDE

my operation is like this๏ผš

  1. issued two ERC20 Tokens on rinkeby

    1. QLC: 0xc211a8cdfff90dca01280d7c90793845499f80a7
    2. QETH: 0x8e212bdfb571ac7a4a149c4d631a03a63aa61ef5
  2. authorize these two tokens to the router contract,just call the approve method of the token contract,

    and I can check the authorization success through the allowance method

  3. call the addLiquidity method of the router contract,router address on the rinkeby is 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D๏ผŒmy parameters are as follows

    1. tokenA:0x8e212bdfb571ac7a4a149c4d631a03a63aa61ef5 // QETH contract address
    2. tokenB:0xc211a8cdfff90dca01280d7c90793845499f80a7 // QLC contract address
    3. amountADesired:10000
    4. amountBDesired:10000
    5. amountAMin:0
    6. amountBMin:0
    7. to:0xB2B98Ac2aC3EB419B17f6cdcA25A0241c3b31bcc //my wallet address
    8. deadline:1629107841

after doing this I encountered an error:

Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending?
gas required exceeds allowance (10000000) or always failing transaction

Can you give me some advice on this error, many thanks

swapExactTokensForETHSupportingFeeOnTransferTokens fails when from == uniswapPair address

I want to apply a fee of the 10% every time my token is transferred (except the case the from is the owner).
When i use PancakeSwap I'm able to create a pool, however, when I try to swap the token from the just created pool, I receive the error 'Pancake: TRANSFER_FAILED'

This happen when the from filed is equal to the _uniswapV2Pair address.

Why this happens and how to fix this problem?

The token code below:

modifier lockSwapTokenForETH {
    _inSwapTokenForETH = true;
    _;
    _inSwapTokenForETH = false;

} 

function _transfer(address from, address to, uint256 amount) private {
     // by adding "from != _uniswapV2Pair" it works
    if (!_inSwapTokenForETH && from != _owner){           
        uint feeAmount = amount * 10 / 100;

        _transfer(from, address(this), feeAmount);
        _swapTokensForEth(feeAmount);   

        _transfer(from, to, amount - feeAmount);
        emit Transfer(from, to, amount - feeAmount);
    }
    else{
        _transfer(from, to, amount);
        emit Transfer(from, to, amount);
    }
}

function _swapTokensForEth(uint256 tokenAmount) private lockSwapTokenForETH {
    address[] memory path = new address[](2);
    path[0] = address(this);
    path[1] = _uniswapV2Router.WETH();

    _approve(address(this), address(_uniswapV2Router), tokenAmount);

    _uniswapV2Router.swapExactTokensForETHSupportingFeeOnTransferTokens(tokenAmount, 0, path, address(this), block.timestamp);
}

receive() external payable {}

getting UniswapV2: LOCKED exception

Hi Uniswap team,
I've encountered an issue when trying to integrate with Uniswap, didn't find anything on google which is similar.

I'm using Genache (forking mainnet).
IDE Remix
Deployment truffle

I did a simple contract which tries to exchange eth -> CDT (and erc20 token)

    function exchangeCDTUniswap(uint256 eth_amount) internal returns(uint256 cdt_bought) {
        address weth = IUniswapV2Router02(uniswap_router).WETH();

        address[] memory path = new address[](2);
        path[0] = weth;
        path[1] = cdt;

        uint[] memory amounts = IUniswapV2Router02(uniswap_router).swapExactETHForTokens{value:eth_amount}(1, path, address(this), now + 15);
        return amounts[1];
    }

uniswap_router = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D
cdt = 0x177d39ac676ed1c67a2b268ad7f1e58826e5b0af

From that call I get UniswapV2: LOCKED which, after looking around, only appears in UniswapV2Pair.sol (here)

What did I do wrong here?

I have a question in function getAmountIn

function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
uint numerator = reserveIn.mul(amountOut).mul(1000);
uint denominator = reserveOut.sub(amountOut).mul(997);
amountIn = (numerator / denominator).add(1);
}

Why is the last line needed call add(1)?

Unreachable Code

This line will always skip the refund code:

https://github.com/Uniswap/uniswap-v2-periphery/blob/4123f93278b60bcf617130629c69d4016f9e7584/contracts/UniswapV2Router01.sol#L258

because of this precondition:

https://github.com/Uniswap/uniswap-v2-periphery/blob/4123f93278b60bcf617130629c69d4016f9e7584/contracts/UniswapV2Router01.sol#L254


I think that the precondition is actually incorrect, and should check that a minimum amount of ETH is provided to complete the trade. Currently, this requires sending the exact amount of ETH to conduct the trade. To fix:

- require(amounts[0] <= msg.value, 'UniswapV2Router: EXCESSIVE_INPUT_AMOUNT'); 
+ require(amounts[0] >= msg.value, 'UniswapV2Router: INSUFFICIENT_INPUT_AMOUNT'); 

yarn test - Failing

  1. ExampleSlidingWindowOracle
    #update
    sets the appropriate epoch slot:

    AssertionError: expected [ Array(3) ] to deeply equal [ Array(3) ]

    • expected - actual
    [
      {
    
    • "_hex": "0x5e0be101"
    • "_hex": "0x5e0be100"
      }
      {
    • "_hex": "0x020000000000000000000000000000"
    • "_hex": "0x00"
      }
      {
    • "_hex": "0x8000000000000000000000000000"
    • "_hex": "0x00"
      }
      ]

    at /uniswap.org/uniswap-v2-periphery/test/ExampleSlidingWindowOracle.spec.ts:330:28

General Question

// given an output amount of an asset and pair reserves, returns a required input amount of the other asset
function getAmountIn(uint amountOut, uint reserveIn, uint reserveOut) internal pure returns (uint amountIn) {
    require(amountOut > 0, 'UniswapV2Library: INSUFFICIENT_OUTPUT_AMOUNT');
    require(reserveIn > 0 && reserveOut > 0, 'UniswapV2Library: INSUFFICIENT_LIQUIDITY');
    uint numerator = reserveIn.mul(amountOut).mul(1000);
    uint denominator = reserveOut.sub(amountOut).mul(997);
    amountIn = (numerator / denominator).add(1);
}

Hi I need to know why this function plus 1 can you explain to me

explore swap to price implementations

once we have a formula from #3 , we'll need to explore ways to approximate this formula on-chain with 0/minimal precision loss, directionally bounded error, etc.

fails with INSUFFICIENT_OUTPUT_AMOUNT

require(amounts[amounts.length - 1] >= amountOutMin, 'UniswapV2Router: INSUFFICIENT_OUTPUT_AMOUNT');

this line seems to be failing a lot, can you elaborate about what causes this?

Why Does SwapToPrice Need The True Price When It Looks Up The Reserves On Chain

IN https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleSwapToPrice.sol, there is a function for computeProfitMaximizingTrade, which takes the true price passed into the smart contract, as well as the reserves as calculated on chain in the smart contract.

What oracle should one use for true price? I'm assuming NOT uniswap itself, because you could derive the price from uniswap onchain. Are you imagining using an Oracle like the sample smart contract oracle? https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/examples/ExampleOracleSimple.sol Or a price feed from somewhere other than Uniswap entirely?

using address[] memory path

Hello,

I'm having some trouble with this:

address[] memory path = new address[](2);
path[0] = uniswapRouter.WETH();
path[1] = _tokenAddress;

path is typed as memory here, and when I try to pass it to swapETHForExactTokens it expects path to be of type calldata.
I receive this error: Type address[] memory is not implicitly convertible to expected type address[] calldata.

How can I convert this to the correct type? Thanks.

Out of gas when deploy UniswapV2Router02.sol

Hello team,

I m trying to learn Uniswap and when I deploy contract UniswapV2Router02.sol via truffle, it always return me error out of gas, even I tried increase very high gasLimit and also run on ganache. I think problem here is size of contract very large. Below is detailed of error:

can be caused by hitting revert in a contract constructor or running out of gas.
   * gas required exceeds allowance (80000290) or always failing transaction.
   * Try: + using the '--dry-run' option to reproduce this failure with clearer errors.
          + verifying that your gas is adequate for this deployment.

Is there anything wrong? Any instruction to deploy this contract?

Thanks.

Contains interface for WETH but no contract

The V2 Router requires the address of the WETH contract. In order to deploy on a local blockchain with truffle. I need to be able to deploy the WETH contract and plug it's address into the deployer. It looks like the WETH9 contract in test contains the functions necessary, although it does not inherit IWEITH. If I'm just missing something please let me know

math error in computeProfitMaximizingTrade

I was working out the math behind computeProfitMaximizingTrade and I discovered an issue there

assuming a, b are reserve0 and reserve1, the math in that function: sqrt(a*b*price/0.997) - a/0.997 differs from what I got by working it back from the spot price: (sqrt(a*b*price) - a)/0.997

Here's how I worked it out:

Starting with price = a / b, then applying the post-trade reserve amounts or price = (a+0.997x)/((a*b) / (a+0.997x)), assuming x is the input amount, we get (a+0.997x)**2 / (a*b)

After expanding that we get (sqrt(a*b*price) - a)/0.997
Screenshot_2021-08-09 Equations and systems solver - MATLAB solve(1)

It's likely that this wasn't noticed so far due to the relatively small impact of this error

Update: the correct formula for spot is actually (a+x)/(a*b / (a+0.997x)), but even with that I can't work it out to sqrt(a*b*price/0.997) - a/0.997 as it's in the contact

There's some other issues hinting that there may be a math bug: #100 #91 - none of them seem to explain the reasoning but price = (a+x)/(a*b / (a+0.997x)) is definitely not solved to x = sqrt(a*b*price/0.997) - a/0.997. When we disregard the fee, my method is consistent with the contract (getting x = sqrt(a*b*price) - a starting from price = (a+x)^2 / (a*b))

Swap with fee

User story: As a developer, I want to integrate with Uniswap while directing a small percentage (or flat fee?) of every trade to an address that I control. This fee could come in the form of the input, the output, either/or, both, or another token after a swap.

This functionality should only be offered for swap* functions. Where should these functions live? Probably in another router?

swapExactETHForTokens() on nodejs its getting reverted by EVM

Hi, im working on a truffle mainnet fork and im trying to execute a swapExactETHForTokens() using web3 but for some reason that i cant understand the swap its getting reverted. Sadly the error message say nothing but revert. Can anyone bring me some help or some insigths, im really stuck.

The code

`module.exports = async function(callback) {

try {
    const accounts = await web3.eth.getAccounts()
    const sender = accounts[0]
    const receiver = accounts[1]

    const UniswapV2Router02 = require('./build/contracts/IUniswapV2Router02.json')
    const daiAddress = '0x6b175474e89094c44da98b954eedeac495271d0f'
    const ethAddress = '0xc02aaa39b223fe8d0a0e5c4f27ead9083c756cc2' 
    const uniRouter02 = new web3.eth.Contract(
       UniswapV2Router02.abi,'0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D')

    const amount = await uniRouter02.methods.swapExactETHForTokens(
        0,
        [ethAddress,daiAddress],
        //[daiAddress,ethAddress],
        receiver,
        1650370580)
        .send({from:sender,value:web3.utils.toWei('5000','Ether')})        

}
catch(error) {
console.log(error)
}

callback()

}`

I appreciate any kind of help

possible division by 0 in UniswapV2Library.sol

It looks like here there's a possibility for denominator to be 0, causing a divide by 0 on the next line. Why not use the SafeMath div function, which provides checks and an error message for divs by 0, instead?

add startTime variable to TradeHelper

Explore adding an earliestStartTIme variable that functions similar to deadline, but the transaction can only be executed after the time is passed.

According to Phil this decreases the MEV (miner extractable value)

Create a contract that computes the value of liquidity shares after arbing to a given 'true' price

This function should consider the protocol fee, and needs to take kLast, reserve0, reserve1, and totalSupply as inputs from the pair

getLiquidityValueAtPrice(address tokenA, address tokenB, uint256 truePriceTokenA, uint256 truePriceTokenB, uint256 liquidityAmount) returns (uint256 tokenAAmount, uint256 tokenBAmount)

E.g.:

If DAI/ETH is 400/1 and the true price of DAI/ETH is 350/1, compute the value of X liquidity shares in terms of DAI and ETH after a trade occurs that moves the marginal price to 350/1 (different from mid price)

flash loan always revert with revert UniswapV2: K

I am writing a fairly simple smart contract in order to do a flash loan but my transaction always revert with the following error UniswapV2: K. I have read 10 000 times the doc explaining the error, but I still don't understand what can be wrong in my code.

    function uniswapV2Call(
        address _sender,
        uint _amount0,
        uint _amount1,
        bytes calldata _data
    ) external {
        address[] memory path = new address[](2);

        address sender = _sender;

        address token0 = IUniswapV2Pair(msg.sender).token0();
        address token1 = IUniswapV2Pair(msg.sender).token1();


        require(
            msg.sender == UniswapV2Library.pairFor(dex1FactoryAddress, token0, token1),
            'Unauthorized'
        );

        require(_amount0 == 0 || _amount1 == 0, 'one amout should be 0');
        require(_amount0 != 0 || _amount1 != 0, 'one amout should be positive');

        uint amoutStartingToken = _amount0 == 0 ? _amount1 : _amount0;
        path[0] = _amount0 == 0 ? token1 : token0;
        path[1] = _amount0 == 0 ? token0 : token1;

        IERC20 startingToken = IERC20(path[0]);
        IERC20 targetToken = IERC20(path[1]);

        startingToken.approve(address(sushiRouter), amoutStartingToken);

        uint amountRequired = UniswapV2Library.getAmountsIn(
            dex1FactoryAddress,
            amoutStartingToken,
            path
        )[0];


        sushiRouter
        .swapExactTokensForTokensSupportingFeeOnTransferTokens(
            amoutStartingToken,
            amountRequired,
            path,
            sender,
            deadline
        );

        assert(targetToken.transfer(msg.sender, amountRequired));
        uint remainingBalance= targetToken.balanceOf(sender);
        assert(targetToken.transfer(tx.origin,  remainingBalance));
    }

For testing purpose I add a 'sync' and 'skim' on both pair before and after flash loan.

I had try this code on ganche-cli and prod and still facing the same issue. Is it a problem with the 'amountRequired' that I am paying back? In the docs it is said that it should be calculated with 'getAmountsIn', that is what I am doing.

What is wrong with my code? I asked on the discord channel + stackoverflow, but it seems no one there knows how to make a flash loan on unsiwap.

Publish to NPM

Let's start publishing this repo to @uniswap/v2-periphery.

Maybe this is the time to set up a CD pipeline for publishing on push to master?

Installation error

Vanilla Installation error ...

C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master>yarn
yarn install v1.22.4
[1/5] Validating package.json...
[2/5] Resolving packages...
[3/5] Fetching packages...
info [email protected]: The platform "win32" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
[4/5] Linking dependencies...
[5/5] Building fresh packages...
[1/13] โข€ sha3 [2/13] โข€ secp256k1 [3/13] โข€ keccak [4/13] โข€ keccak error C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\sha3: Command failed.
Exit code: 1
Command: node-gyp rebuild
Arguments:
Directory: C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\sha3
Output:
C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\sha3>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\....\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "" rebuild )
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | win32 | x64
gyp ERR! configure error
gyp ERR! stack Error: Command failed: C:\Users\Alexander Bradley\AppData\Local\Programs\Python\Python36\python.EXE -c import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack File "", line 1
gyp ERR! stack import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack ^
gyp ERR! stack SyntaxError: invalid syntax
gyp ERR! stack
gyp ERR! stack at ChildProcess.exithandler (child_process.js:294:12)
gyp ERR! stack at ChildProcess.emit (events.js:188:13)
gyp ERR! stack at maybeClose (internal/child_process.js:978:16)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:265:5)
gyp ERR! System Windows_NT 10.0.18362
gyp ERR! command "C:\Program Files\nodejs\node.exe" "C:\Program Files\nodejs\node_modules\npm\node_modules\node-gyp\bin\node-gyp.js" "rebuild"
gyp ERR! cwd C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\sha3
warning Error running install script for optional dependency: "C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\scrypt: Command failed.
Exit code: 1
Command: node-gyp rebuild
Arguments:
Directory: C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\scrypt
Output:
C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\scrypt>if not defined npm_config_node_gyp (node "C:\Program Files\nodejs\node_modules\npm\bin\node-gyp-bin\\..\..\node_modules\node-gyp\bin\node-gyp.js" rebuild ) else (node "" rebuild )
gyp info it worked if it ends with ok
gyp info using [email protected]
gyp info using [email protected] | win32 | x64
gyp ERR! configure error
gyp ERR! stack Error: Command failed: C:\Users\Alexander Bradley\AppData\Local\Programs\Python\Python36\python.EXE -c import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack File "", line 1
gyp ERR! stack import sys; print "%s.%s.%s" % sys.version_info[:3];
gyp ERR! stack ^
gyp ERR! stack SyntaxError: invalid syntax
gyp ERR! stack
gyp ERR! stack at ChildProcess.exithandler (child_process.js:294:12)
gyp ERR! stack at ChildProcess.emit (events.js:188:13)
gyp ERR! stack at maybeClose (internal/child_process.js:978:16)
gyp ERR! stack at Process.ChildProcess._handle.onexit (internal/child_process.js:265:5)
gyp ERR! System Windows_NT 10.0.18362
gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files\\nodejs\\node_modules\\npm\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild"
gyp ERR! cwd C:\Users\Alexander Bradley\Downloads\uniswap-v2-periphery-master\uniswap-v2-periphery-master\node_modules\scrypt
gyp ERR! node -v v11.6.0
gyp ERR! node-gyp -v v3.8.0
gyp ERR! not ok"
info This module is OPTIONAL, you can safely ignore this error

TransferHelper: TRANSFER_FROM_FAILED

image

react_devtools_backend.js:2557 Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"code":-32603,"message":"execution reverted: TransferHelper: TRANSFER_FROM_FAILED","data":{"originalError":{"code":3,"data":"0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000245472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c454400000000000000000000000000000000000000000000000000000000","message":"execution reverted: TransferHelper: TRANSFER_FROM_FAILED"}}}, method="estimateGas", transaction={"from":"0x7F87bBc2Eb7911c8961c8506032d31d624894725","to":"0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D","value":{"type":"BigNumber","hex":"0x0de0b6b3a7640000"},"data":"0xf305d719000000000000000000000000c936c5a29f55006f2b1c84480bf2d77286e5944300000000000000000000000000000000000027716b6a0adc2d677c080000000000000000000000000000000000000000000027716b6a0adc2d677c08000000000000000000000000000000000000000000000000000000000de0b6b3a76400000000000000000000000000007f87bbc2eb7911c8961c8506032d31d6248947250000000000000000000000000000000000000000000000000000000060a5149c","accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.1.1)
    at e.value (index.ts:205)
    at e.value (index.ts:217)
    at E (json-rpc-provider.ts:76)
    at n.<anonymous> (json-rpc-provider.ts:508)
    at c (runtime.js:63)
    at Generator._invoke (runtime.js:293)
    at Generator.throw (runtime.js:118)
    at s (4.1d476024.chunk.js:2)

Help?

why is the trading fee applied by reducing the token paid instead of the token received?

Excuse me, why is the trading fee applied by reducing the token paid instead of the token received?

If the 0.003 trade fee happens in the token received, the impermanence loss could be reduced to a certain extent.

Under the current model, in one-sided market, the trading fee will always be charged for the token that is about to depreciate.

For LP providers, after uniswap has been running for a period of time, as long as the current price has changed from the original price, the impermanence loss of charging for receive token is smaller than the current model. This may attract more people to become LP providers.

Problem using UniswapRouter swapTokensForExactTokens on Kovan Network

I'm trying to make a wrapper contract to exchange token for exact tokens. But all the time I get the error:
Gas estimation errored with the following message (see below). The transaction execution will likely fail. Do you want to force sending? The execution failed due to an exception. Reverted

(I'm sure that I set a proper gas limit)

Here is the contract code:

pragma solidity =0.6.6;

import "https://github.com/Uniswap/uniswap-v2-periphery/blob/master/contracts/interfaces/IUniswapV2Router02.sol";

contract UniswapExample {
    address internal constant UNISWAP_ROUTER_ADDRESS = 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D ;
    IUniswapV2Router02 public uniswapRouter;
    
    constructor() public {
        uniswapRouter = IUniswapV2Router02(UNISWAP_ROUTER_ADDRESS);
    }

    function convertTokenToToken() public {    
        address[] memory path = new address[](2);
        path[0] = 0xd0A1E359811322d97991E03f863a0C30C2cF029C;
        path[1] = 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984;
        uint amountOut = 1000000000000000000;
        uint amountInMax = 81421557334496861;
        address to = 0x9924b75Af301D9F2801DEA27f598fc8156c71732;
        uint deadline = 1669238436;
        // Exchanging WETH for 1 UNI
        uniswapRouter.swapTokensForExactTokens(amountOut, amountInMax, path, to, deadline);

      }
}

The amountInMax at the time of writing was sufficient for the swap.
Deployed contract address at Kovan network: 0x22eea44c390F23fA7F1420C233e20d1e061f4B48

Swap and add liquidity

User story: I want to add liquidity to a uniswap pool but only have balances in a single token, i want to swap enough so that i can then use my proceeds to add liquidity at exactly the ending price.

Should we add this functionality to the base router, or create an extension? What do the slippage parameters look like for this function?

Proposal: addLiquiditySupportingFeeOnTransfer

The addLiquidity function assumes there is no transfer-tax on either of the tokens. In case one of the tokens has a tax, too much of the other will be sent to the pair, resulting in waste for the user.

https://github.com/Uniswap/uniswap-v2-periphery/blob/dda62473e2da448bc9cb8f4514dadda4aeede5f4/contracts/UniswapV2Router02.sol#L73-L74

We propose a new function.

function addLiquiditySupportingFeeOnTransfer(
    address feeToken, 
    address tokenB, 
    uint amountFeeTokenDesired,
    uint amountBDesired,
    uint amountFeeTokenMin,
    uint amountBMin,
    address to,
    uint deadline
) external returns (uint amountFeeToken, uint amountB, uint liquidity);

addLiquiditySupportingFeeOnTransfer is similar to addLiquidity in that it calculates the quote beforehand, however, it first sends the feeToken to the pair. Afterwards it scales down the amount of tokenB to send to the pair based on how much of the feeToken actually arrived.

function addLiquiditySupportingFeeOnTransfer(
    address feeToken,
    address tokenB,
    uint amountFeeTokenDesired,
    uint amountBDesired,
    uint amountFeeTokenMin,
    uint amountBMin,
    address to,
    uint deadline
) external virtual override ensure(deadline) returns (uint amountFeeToken, uint amountB, uint liquidity) {
    (amountFeeToken, amountB) = _addLiquidity(feeToken, tokenB, amountFeeTokenDesired, amountBDesired, amountFeeTokenMin, amountBMin);
    address pair = UniswapV2Library.pairFor(factory, feeToken, tokenB);
    uint256 before = IERC20(feeToken).balanceOf(pair);
    TransferHelper.safeTransferFrom(feeToken, msg.sender, pair, amountFeeToken);
    uint amountBReduced = IERC20(feeToken).balanceOf(pair).sub(before).mul(amountB).div(amountFeeToken); // Pro-rata adjustment
    if(amountBReduced < amountB) // We only want to decrease amount B
        amountB = amountBReduced;
    TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
    liquidity = IUniswapV2Pair(pair).mint(to);
}

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.