0

These codes send a transaction to uniswap contract and charge some handling fee, adding Liquidity to the Capital pool. However, I don't know where the "_transfer" function is wrong, which calls fpoSwap.swapAndLiquidity(), a method in the "FPOSwap" contract . It raises a transfer error. I test the "swapTokensForToken" function and "addLiquidity" function, respectively, and they all pass. This is transfer function

function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(amount > 0,"FPO: transfer amount the zero");
        require(sender != address(0), "FPO: transfer from the zero address");
        require(recipient != address(0), "FPO: transfer to the zero address");
        _beforeTokenTransfer(sender, recipient, amount);
        _balances[sender] = _balances[sender].sub(amount, "FPO: transfer amount exceeds balance");
        if((automatedMarketMakerPairs[sender] || automatedMarketMakerPairs[recipient]) &&
            !excludeFromFees[recipient] && !excludeFromFees[sender] && fee > 0 && !swapping){
            swapping = true;
            uint256 feeAmount = amount.mul(fee).div(100);
            amount = amount.sub(feeAmount);
            _balances[address(fpoSwap)] = _balances[address(fpoSwap)].add(feeAmount);
            emit Transfer(address(sender), address(fpoSwap), feeAmount);
            if(_balances[address(fpoSwap)] > 100000000){
                fpoSwap.swapAndLiquidity();
            }
            swapping = false;
        }
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

This is fpoSwap contract

function swapTokensForToken(uint256 tokenAmount) public onlyOwner {
        address[] memory path = new address[](2);
        path[0] = address(fpo);
        path[1] = address(usd);

        fpo.approve(address(router), tokenAmount);
        router.swapExactTokensForTokensSupportingFeeOnTransferTokens(
            tokenAmount,
            0, // accept any amount of ETH
            path,
            address(this),
            block.timestamp
        );
    }

    function addLiquidity(uint256 tokenAmount, uint256 usdAmount) public onlyOwner {
        // approve token transfer to cover all possible scenarios
        fpo.approve(address(router), tokenAmount);
        usd.approve(address(router),usdAmount);

        // add the liquidity
        router.addLiquidity(
            address(fpo),
            address(usd),
            tokenAmount,
            usdAmount,
            0, // slippage is unavoidable
            0, // slippage is unavoidable
            address(0),
            block.timestamp
        );
    }

    function swapAndLiquidity() public override onlyFPO {
        uint256 tokens = fpo.balanceOf(address(this));
        uint256 half = tokens.div(2);
        uint256 otherHalf = tokens.sub(half);
        swapTokensForToken(half);
        uint256 usdBalance = usd.balanceOf(address(this));
        addLiquidity(otherHalf, usdBalance);
        emit SwapAndLiquidity(half, usdBalance, otherHalf);
    }
Yg Hu
  • 1
  • 1
  • have you deployed the code into any testnet? If yes can you please share the tx of the error, I will take a look at the scan. – PySoL Feb 17 '22 at 06:30
  • Thank you for your reply!I can provide you with testnet RPC address and hash. Can you find the information you want? – Yg Hu Feb 17 '22 at 09:49
  • yeah, if it's public, then you can put it somewhere I people can access. – PySoL Feb 17 '22 at 10:40
  • RPC:http://test.rpc.mebit.cc,tx:0xc1deb74e1d9398369d2b8ee701dba74b343263f6e4a7c1a7eb70168e88e3ba0e – Yg Hu Feb 18 '22 at 01:33

2 Answers2

0

Can not access to the resource you provided, but can not access.

So far, there're things that we could do to resolve it:

  1. Test swapAndLiquidity() respectively, by directly leave some token in the contract.
  2. Comment out the fpoSwap.swapAndLiquidity(); and test where the the fee is applied correctly.
  3. Call the swapAndLiquidity() manually under this condition: _balances[address(fpoSwap)] > 100000000.
  4. If 1, 2, 3 successful, then we can un-comment the 2 in the transfer function and test the Simple transfer only.
  5. Finally, we can continue with the transfer via a 3rd party like uniswap.
PySoL
  • 566
  • 3
  • 9
  • I've tested ```FpoSwap ``` and all three methods and ```_transfer``` they all pass.But But put them together and report an error,They all have enough token balances – Yg Hu Feb 18 '22 at 05:42
  • Thank you for your idea, but now I have a new problem. I hope you can help me check the code – Yg Hu Feb 18 '22 at 10:01
  • How do you call the transfer function? Directly or using the swap function of the dex? Besides that, what is the error message that you've got? – PySoL Feb 19 '22 at 15:38
  • and what does the `_beforeTokenTransfer` do? – PySoL Feb 19 '22 at 15:39
  • Error message from ->"TransferHelper.safeTransferFrom"."TransferHelper: TRANSFER_FROM_FAILED" ,"Pair.swap"->"MdexSwap: INSUFFICIENT_OUTPUT_AMOUNT" – Yg Hu Feb 20 '22 at 10:19
  • 1. Please make sure that you only call the transfer function directly, without using any swap. 2. You only able to call swap and liquidity in case of swap BUSD -> FOO token. – PySoL Feb 20 '22 at 15:52
  • I executed swap in swap, but I can't execute the same transaction in swap, right? – Yg Hu Feb 21 '22 at 01:47
  • I implemented "swap" and "liquidity" in "USD - > FPO swap" – Yg Hu Feb 21 '22 at 01:59
  • You're able to swapAndLiquidify in the same swap transaction. But it's only in case you're trying to swap USD -> FPO. If the `swapAndLiquidify` called while you're swapping from FPO -> USD. Probably you've got error, router doesn't allow us do it. – PySoL Feb 21 '22 at 02:16
0
function _transfer(address sender, address recipient, uint256 amount) internal virtual {
        require(amount > 0,"FPO: transfer amount the zero");
        require(sender != address(0), "FPO: transfer from the zero address");
        require(recipient != address(0), "FPO: transfer to the zero address");
        _beforeTokenTransfer(sender, recipient, amount);
        _balances[sender] = _balances[sender].sub(amount, "FPO: transfer amount exceeds balance");
        if((automatedMarketMakerPairs[sender] || automatedMarketMakerPairs[recipient]) &&
            !excludeFromFees[recipient] && !excludeFromFees[sender] && fee > 0 && !swapping){
            swapping = true;
            uint256 feeAmount = amount.mul(fee).div(100);
            amount = amount.sub(feeAmount);
            _balances[address(fpoSwap)] = _balances[address(fpoSwap)].add(feeAmount);
            emit Transfer(address(sender), address(fpoSwap), feeAmount);
            if(_balances[address(fpoSwap)] > 100000000 && runSwapping){
                fpoSwap.swapAndLiquidity();
            }
            swapping = false;
        }
        _balances[recipient] = _balances[recipient].add(amount);
        emit Transfer(sender, recipient, amount);
    }

    function _runSwapAndLiquidity() internal virtual {
        fpoSwap.swapAndLiquidity();
    }

"Fposwap. Swapandliquidity" can be executed separately, but an error will be reported when it is placed in "_transfer"

Yg Hu
  • 1
  • 1