0

Could someone help me understand what I'm doing wrong and how to fix this? I am trying to implement an Uniswap bot in Goerli testnet, that will buy or sell tokens with WETH under some circumstances. But I faces with an issue, that happens when the bot has to swap back(there are no issues when it buys tokens with WETH regardless what decimals token is) token(that is not 18 decimals) to WETH. In the main function I initially call the swap function to buy token with WETH like this(ICO_BOT.weth_buy_threshold is a constant ==0.01 WEH):

self.swap_token(token_in,token_out,ICO_BOT.weth_buy_threshold)

and in case of some conditions I want swap token back to WETH:

self.swap_token(token_in, token_out, self.get_token_balance(token_in)) 

So when I swap the tokens back I get the balance of this token in smart contract and pass it in the swap function.

This is the implementation of swap_token, get_min_amount_to_buy functions and get_balance in Python:

    def get_min_amount_to_buy(self,token_in,token_out, amount_to_buy):
        try:
            res = ICO_BOT.my_contract.functions.getAmountOutMin(token_in,token_out,amount_to_buy).call()
            print(f'It should return about {res} of token {token_out} for {amount_to_buy} of {token_in} token')
            return res  #ICO_BOT.weth_buy_threshold
        except web3.exceptions.ContractLogicError:
            print(f'Not enough liquidity. Try another pair or another amount')
            return None

    def swap_token(self,token_in,token_out,amount_to_buy):
        if self.get_min_amount_to_buy(token_in,token_out,amount_to_buy) is not None and self.get_min_amount_to_buy(token_in,token_out,amount_to_buy)!=0:
            nonce = ICO_BOT.w3.eth.get_transaction_count(ICO_BOT.my_address_in_goeri)
            tx = ICO_BOT.my_contract.functions._swap_token(token_in,token_out,amount_to_buy,self.get_min_amount_to_buy(token_in,token_out,amount_to_buy),ICO_BOT.my_contract_address).build_transaction({'nonce':nonce,'gas':ICO_BOT.gas})
            signed_tx = ICO_BOT.w3.eth.account.signTransaction(tx, ICO_BOT.private_key)
            ICO_BOT.w3.eth.sendRawTransaction(signed_tx.rawTransaction)
        else:
            print(f'we cannot swap these tokens due to the lack of liquidity')
            return None
    def get_token_balance(self,token):
        return ICO_BOT.my_contract.functions.get_balance_token(token).call()

Solidity code to get min amount to swap and swap function itself.

    function _swap_token(address  _token_in,address  _token_out,uint _amountIn,uint _amountOutMin,address _to) external{
        address[] memory path;
        if (_token_in==WETH_Goerli || _token_out == WETH_Goerli){ 
        path = new address[](2);
        path[0]=_token_in;
        path[1] = _token_out;}
        else {
            path = new address[](3);
            path[0] = _token_in;
            path[1] = WETH_Goerli;
            path[2] = _token_out;
        }
        IUniswapV2Router(uniswap_goerli).swapExactTokensForTokens(_amountIn, _amountOutMin, path, _to, block.timestamp);
 }

       function getAmountOutMin(address _tokenIn, address _tokenOut, uint256 _amountIn) external view returns (uint256) {

        address[] memory path;
        if (_tokenIn == WETH_Goerli || _tokenOut == WETH_Goerli) {
            path = new address[](2);
            path[0] = _tokenIn;
            path[1] = _tokenOut;
        } else {
            path = new address[](3);
            path[0] = _tokenIn;
            path[1] = WETH_Goerli;
            path[2] = _tokenOut;
        }
        
        uint256[] memory amountOutMins = IUniswapV2Router(uniswap_goerli).getAmountsOut(_amountIn, path);
        return amountOutMins[path.length -1];}

    function get_balance_token(address _token) public view returns(uint){
        return ERC20(_token).balanceOf(address(this));
    }

Although get_min_amount_to_buy returns (as I can see) the correct amount for to swap both for tokens with 18 decimals and non 18 decimals It should return about 9946580332182532 of token 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6 for 16619667422237978856 of 0xfDf686FB601A8dcC6865f02Ac4BfA8A2F14578f8 token - swap is successful

It should return about 9963047159820956 of token 0xB4FBF271143F4FBf7B91A5ded31805e42b2208d6 for 24021055262063930508653 of 0xE8905d43d4c545Dd8f693DECABF06B161D61ca5C token - error during the swap

I'm getting the error: Fail with error 'UniswapV2: K' error

Please advice how can I fix this! Thank you in advance!

1

1 Answer 1

1

according to uniswap the “K” error means that a trade was attempted that somehow left the trading pair with less reserves than should be there, and as a result the transaction is reverted.

This geranlly happens when either one of the two tokens to be swapped is taking any types of transfer fee or taxation.

4
  • Usually "K" error comes because swap amounts are so small that there is a rounding error. Jan 2, 2023 at 9:16
  • Thank you, Safi! It's probably my case. I substituted swapExactTokensForTokens to swapExactTokensForTokensSupportingFeeOnTransferTokens function. So far so good.Now I'm getting different errors:))
    – Alex
    Jan 29, 2023 at 21:19
  • @Alex what error are you getting now?
    – Safi
    Jan 30, 2023 at 8:19
  • I created a new ticket for this question: ethereum.stackexchange.com/questions/143909/…. When the bot tries to swap the token back to WETH for some of the tokens the transaction fails with TRANSFER_FROM_FAILED:(
    – Alex
    Jan 30, 2023 at 9:19

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.