Yg Hu
Yg Hu

Reputation: 1

Uniswap error:A transfer error ocurred when invoking `fpoSwap.swapAndLiquidity()` in the `_transfer` function

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);
    }

Upvotes: 0

Views: 281

Answers (2)

Yg Hu
Yg Hu

Reputation: 1

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"

Upvotes: 0

PySoL
PySoL

Reputation: 576

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.

Upvotes: 0

Related Questions