11

I'm trying to use Uniswapv2Router with Truffle and Ganache, but haven't been able to identify what I'm doing wrong. I'm using addLiquidty method as follows: await uniswapV2Router02.addLiquidity(token0.address, token1.address, 500, 250, 250 , 125, accounts[0], 1618158769);Which throws error Error: Returned error: VM Exception while processing transaction: revert ds-math-sub-underflow -- Reason given: ds-math-sub-underflow.

But If I comment out .minto(to) The code executes properly until there.

    function addLiquidity(
        address tokenA,
        address tokenB,
        uint amountADesired,
        uint amountBDesired,
        uint amountAMin,
        uint amountBMin,
        address to,
        uint deadline
    ) external ensure(deadline) returns (uint amountA, uint amountB, uint liquidity) {
        (amountA, amountB) = _addLiquidity(tokenA, tokenB, amountADesired, amountBDesired, amountAMin, amountBMin);
        address pair = UniswapV2Library.pairFor(factory, tokenA, tokenB);
        TransferHelper.safeTransferFrom(tokenA, msg.sender, pair, amountA);
        TransferHelper.safeTransferFrom(tokenB, msg.sender, pair, amountB);
        IUniswapV2Pair(pair);//.mint(to);
    }

This happens even if I have a simple mint implementation just for testing what is going on.

  function mint(address to) external lock returns (uint liquidity) {
        liquidity = 3;
    }

6 Answers 6

9

This also happens if the Uniswap token related to the pool has not been approved for the wallet sending the transaction.

Solution: Call the approve method of the new Pair contract with spender as 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D

0
8

The problem was because when using UniswapV2Factory, only the precompiled UniswapV2Factory contract in the build directories from @uniswap should be deployed as stated in docs https://uniswap.org/docs/v2/smart-contract-integration/quick-start/. So, even if I commented out something on my UniswapV2Pair contract, it had no effect, because UniswapV2Factory uses a precompiled UniswapV2Pair contract as well. On the other hand, the ds-math-sub-underflow error was because on the UniswapV2Pair contract, the function mint(address to) retrieves its balance of each token, and because it hadn't enough, liquidity = Math.sqrt(amount0.mul(amount1)).sub(MINIMUM_LIQUIDITY); caused an underflow.

4

"UniswapV2 addLiquidity revert ds-math-sub-underflow" error happened because "msg.value" parameter has not been provided for calling "addLiquidity" method.

Now call the addLiquidity method as:

await uniswapV2Router02.addLiquidity(token0.address, token1.address, 500, 250, 250 , 125, accounts[0], 1618158769, {value : "125"});

The same "value" parameter should also be passed for calling swap methods like "swapExactETHForTokens".

This is the exact reason for this error.

Note: Don't forget to change the deadline parameter in the function:

addLiquidity(address tokenA,address tokenB,uint amountADesired, uint amountBDesired,uint amountAMin,uint amountBMin,address to,uint deadline)

1
  • Thanks! the addition of {value:125} to addLiquidityEth got around my issue of TransferHelper: TRANSFER_FROM_FAILED.
    – rsmets
    Commented Mar 2, 2022 at 17:33
2

Underflow usually only occurs from math operations, in this case the underflow error looks to be from the parameters you passed in as amountA and amountB. The same issue occurs when working with pancakeSwap, the minimum amount to be inputted is 1000. Doing so fixed my underflow issue, hope it fixes yours!

1
  • As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.
    – Community Bot
    Commented Aug 2, 2022 at 9:50
2

you should change 500, 250 to 1001 + look pair docs https://docs.uniswap.org/protocol/V2/reference/smart-contracts/pair MINIMUM_LIQUIDITY function MINIMUM_LIQUIDITY() external pure returns (uint); Returns 1000 for all pairs. See Minimum Liquidity.

1

This error occurs when in addLiquidity or removeLiquidity (I encountered this error when I wanted to removeLiquidity) via Uniswap router, it's because the caller is the router address or your smart contract address not the owner address!

So For add liquidity:

    function addLiquidity(address tokenA,
            address tokenB,
            uint amountADesired,
            uint amountBDesired,
            uint amountAMin,
            uint amountBMin,
            address to,
            uint deadline) 
            external returns (uint amountA,
            uint amountB,
            uint liquidity) 

and for removing liquidity:

function removeLiquidity(address tokenA,
            address tokenB,
            uint liquidity,
            uint amountAMin,
            uint amountBMin,
            address to,
            uint deadline) 
            external returns (uint amountA,
            uint amountB) 

You should declare 'to' address to address(this).

By using address(this) as the caller, the contract performs the operation on the user's behalf.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.