0

Context I am trying to build a smart contract of a ERC20 token which comprehends the creation of the relative WETH/token pair on Uniswap V2.

Code The smart contract is as follow:

// SPDX-License-Identifier: MIT

pragma solidity ^0.8;

import "@openzeppelin/contracts/utils/Address.sol";
import "@openzeppelin/contracts/utils/Context.sol";
import "@openzeppelin/contracts/access/Ownable.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@uniswap/v2-core/contracts/interfaces/iUniswapV2Factory.sol";
import "@uniswap/v2-core/contracts/interfaces/iUniswapV2Pair.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IUniswapV2Router02.sol";
import "@uniswap/v2-periphery/contracts/interfaces/IWETH.sol";

contract BarnaTokenInu is Ownable, ERC20 {
using Address for address;

string constant __name = "BARNATOKENINU";
string constant __symbol = "BTI";
uint256 constant __decimals = 18;
uint256 constant initialInvestment = 0.002 * 10**18;
uint256 constant fractionForOwner = 20;
uint256 constant deadlineForLiquidityProvision = 20 * 60;
uint256 constant initialSupply = 1e9 * 10**__decimals;
address public router_address;
IUniswapV2Router02 public router;
IUniswapV2Factory public factory;
IUniswapV2Pair public pair;
address public liquidityPoolPair;
IWETH public iweth; // weth object interface
IERC20 public weth;

constructor(address _router_address) ERC20(__name, __symbol) {
    router_address = _router_address;
    router = IUniswapV2Router02(router_address);
    factory = IUniswapV2Factory(router.factory());
    liquidityPoolPair = factory.createPair(router.WETH(), address(this));
    pair = IUniswapV2Pair(liquidityPoolPair);
    iweth = IWETH(router.WETH());
    weth = IERC20(router.WETH());

    _approve(owner(), router_address, type(uint256).max);
    _approve(address(this), router_address, type(uint256).max);
    _mint(owner(), initialSupply); // mint token
}

function getPoolReserves() public view returns (uint112, uint112) {
    (uint112 reserveToken1, uint112 reserveToken2, ) = pair.getReserves();
    return (reserveToken1, reserveToken2);
}

function swapETHforWETH() public payable {
    iweth.deposit{value: msg.value}();
    weth.transfer(msg.sender, msg.value);
}

function addInitialLiquidity() public payable onlyOwner {
    
    weth.approve(router_address, initialInvestment);
    weth.approve(owner(), initialInvestment);
    router.addLiquidityETH{value: msg.value}(
        address(this),
        (initialSupply * fractionForOwner) / 100,
        (initialSupply * fractionForOwner) / 100,
        initialInvestment,
        owner(),
        block.timestamp + deadlineForLiquidityProvision
    );
}

The brownie main script from which the smart contract is deployed is as follows:

def deploy_token_contract(_account):
    if network.show_active() in LOCAL_DEVELOPMENT_ENVIRONMENTS:
        router = get_account(index=9)
    else:
        router = config["networks"][network.show_active()]["router_address"]
    return BarnaTokenInu.deploy(router, {"from": _account})


def main():
    account = get_account()
    contract = deploy_token_contract(account)
    contract.swapETHforWETH({"from": account, "value": 0.02 * 10**18})
    contract.addInitialLiquidity({"from": account, "value": 0.02 * 
    10**18})

Issue After the creation of the pair, I am not able to add liquidity to the pool, given that:

  • I have enough ETH in my account
  • I have made all the due approvals

I keep receiving the following error:

    VirtualMachineError: revert: TransferHelper: TRANSFER_FROM_FAILED

Full error trace:

    Transaction sent: 0x7ffd26ac40fe40b9eb211b94402b8ddcc60ebb311178755c457b393b34035f87
    Gas price: 0.0 gwei   Gas limit: 12000000   Nonce: 20
    BarnaTokenInu.addInitialLiquidity confirmed (TransferHelper: TRANSFER_FROM_FAILED)   
    Block: 15919924   Gas used: 87214 (0.73%)

    File "C:\Users\sma157555\AppData\Local\Programs\Python\Python310\lib\site- 
    packages\brownie\_cli\run.py", line 51, in main
    return_value, frame = run(
    File "C:\Users\sma157555\AppData\Local\Programs\Python\Python310\lib\site- 
    packages\brownie\project\scripts.py", line 110, in run
    return_value = f_locals[method_name](*args, **kwargs)
    File ".\scripts\main.py", line 30, in main
    contract.addInitialLiquidity({"from": account})
    File "C:\Users\sma157555\AppData\Local\Programs\Python\Python310\lib\site- 
    packages\brownie\network\contract.py", line 1861, in __call__
    return self.transact(*args)
    File "C:\Users\sma157555\AppData\Local\Programs\Python\Python310\lib\site- 
    packages\brownie\network\contract.py", line 1734, in transact
    return tx["from"].transfer(
    File "C:\Users\sma157555\AppData\Local\Programs\Python\Python310\lib\site- 
    packages\brownie\network\account.py", line 682, in transfer
    receipt._raise_if_reverted(exc)
    File "C:\Users\sma157555\AppData\Local\Programs\Python\Python310\lib\site- 
    packages\brownie\network\transaction.py", line 446, in _raise_if_reverted
    raise exc._with_attr(
    VirtualMachineError: revert: TransferHelper: TRANSFER_FROM_FAILED
    Trace step -1, program counter 3601:
    File "contracts/BarnaTokenInu.sol", lines 183-190, in BarnaTokenInu.addInitialLiquidity:

    weth.approve(router_address, initialInvestment);
    weth.approve(owner(), initialInvestment);
    router.addLiquidityETH(
        address(this),
        (initialSupply * fractionForOwner) / 100,
        (initialSupply * fractionForOwner) / 100,
        initialInvestment,
        owner(),
        block.timestamp + deadlineForLiquidityProvision
    );
}

Is anybody able to detect the flaw?

EDIT - SOLVED

I was unable to add liquidity because the add liquidity transaction sender is the contract from which the function is called...and there were no tokens on it...once I minted some tokens during contract deployment, everything worked

0

Your Answer

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

Browse other questions tagged or ask your own question.