node.jssolidityswapweb3jserc20

Rinkeby Uniswap swapExactETHForTokens - Fail with error 'UniswapV2Router: EXPIRED'


Ideally, I need example of correct transaction format in web3 or ethers, Where it can swap WETH for ERC20 or ERC20 for WETH using UniswapV2Router on Rinkeby, I think, I'm having wrong transaction format, maybe it's because of gasPrice or gasLimit, but I don't understand where it happens, So I tried with the increased gasPrice(100 Gwei) and gasLimit(8,000,000) but it's still failing, I also decreased the "amountOutMin" to 1, Transaction deadline is 20 minutes but it's failiing in a few seconds

Swap 1 Ether for UNI (WETH and ETH balances are more than 5 on sender's address) transaction deadline: 20 minute UNI address: 0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984 UniswapV2Router: 0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D Another small question, when you swap ETH for ERC20 does it takes WETH or ETH from senders balance?

const swap  = async () => {
try{
    const chainId = ChainId.RINKEBY 

    const tokenAddress = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984" 
    const uni = await Fetcher.fetchTokenData(chainId, tokenAddress)
    const weth = WETH[chainId]
    const pair = await Fetcher.fetchPairData(uni, weth) 
    const route = new Route([pair], weth)  
    const trade = new Trade(route, new TokenAmount(weth, '100000000000000000'), TradeType.EXACT_INPUT) 

    console.log('1 WETH for', route.midPrice.toSignificant(6), ' UNI')
    console.log('1 UNI for', route.midPrice.invert().toSignificant(6), ' WETH')
    console.log('Trade price 1 WETH for ', trade.executionPrice.toSignificant(6), ' UNI') 

    const accounts =  await web3.eth.getAccounts()
    const account = accounts[0] 
    const slippageTolerance = new Percent('20', '100')
    const path = [weth.address, uni.address ]
    const to = account 
    
    // function toHex(currencyAmount) {
    //     return `0x${currencyAmount.raw.toString(16)}`
    // } 
    // const amountOutMin = toHex(trade.minimumAmountOut(slippageTolerance))
    // const value = toHex(trade.inputAmount)

  
    const uniswap = await new web3.eth.Contract(abi, "0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D") 
    const now = moment().unix()  
    const DEADLINE = now + 60 *20   

    console.log('Sending...') 
    let txn = await uniswap.methods.swapExactETHForTokens(  1,  path,  to,   DEADLINE   ).send( { 
        from: account, 
        gasLimit: 8000000,  
        gasPrice: web3.utils.toWei('100', 'Gwei'), 
        value: web3.utils.toWei('1', 'Ether')  
    })
    console.log(`Txn: https://rinkeby.etherscan.io/tx/${txn.transactionHash}`) 

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

module.exports = swap

Transaction results on rinkeby etherscan: enter image description here

Console:

"Error: Transaction has been reverted by the EVM "


Solution

  • Here is an example of swapping ETH to UNI. I am using ethJS.

    const WETH_ADDRESS = "0xc778417e063141139fce010982780140aa0cd5ab";
    const UNI_ADDRESS = "0x1f9840a85d5aF5bf1D1762F925BDADdC4201F984";
    const path = [WETH_ADDRESS, UNI_ADDRESS];
    const ethAmount = ethers.utils.parseEther("0.1");
    
    const nowInSeconds = Math.floor(Date.now() / 1000)
    const expiryDate = nowInSeconds + 900;
    
    const txn = await uniswapV2Contract.swapExactETHForTokens(
        0,
        path,
        user.address,
        expiryDate,
        {
            gasLimit: 1000000,
            gasPrice: ethers.utils.parseUnits("10", "gwei"),
            value: ethAmount
        }
    )
    const res = await txn.wait();
        
    

    When you call the method swapExactETHForTokens, it would be taking ETH and not WETH. If you would like to swap with WETH, you should call swapExactTokensForTokens.