[Ethereum] swapExactETHForTokens function execution

binanceerrorpancakeswappythonweb3.py

Please, help me. I try to do swapExactETHForTokens function from PancakeSwap Router contract. It's my code:

def swap_exact_eth(router_contract_sample,
                   token_contract,
                   amount_out_min,
                   path,
                   to,
                   deadline,
                   gas,
                   gas_price,
                   nonce):

    approve_value = allowance_function(token_contract, router_contract_sample)
    print('approve_value: ', approve_value)
    estimate_gas = router_contract_sample.functions.swapExactETHForTokens(
        amount_out_min,
        path,
        to,
        deadline
    ).estimateGas({'value': approve_value})
    print('estimate_gas for swap: ', estimate_gas)
    swap_builder = router_contract_sample.functions.swapExactETHForTokens(
        amount_out_min,
        path,
        to,
        deadline
    ).buildTransaction(
        {
            'nonce': nonce,
            'gas': gas,
            'gasPrice': gas_price,
            'value': approve_value
        }
    )

    tx_hash, tx_status = get_tx_details(swap_builder)
    return tx_hash, tx_status

router_contract = contract
main_token_contract = get_contract_instance(
    token_name='Tether USD',
    token_symbol='USDT',
    token_address=w3.toChecksumAddress('0x7ef95a0FEE0Dd31b22626fA2e10Ee6A223F8a684')
)

# nonce = w3.eth.getTransactionCount(bot_address)

# Создаем экземпляр контракта weth (wbnb)
wbnb_token_contract = get_contract_instance(
    token_name='Wrapped BNB',
    token_symbol='WBNB',
    token_address=w3.toChecksumAddress('0xae13d989daC2f0dEbFf460aC112a837C89BAa7cd')
)


# getAmountsOut
get_amounts_out = contract.functions.getAmountsOut(
    1000000000000000000,
    [wbnb_token_contract.address, main_token_contract.address]
).call()
print('wbnb need amount: ', get_amounts_out[0])
print('usdt need amount: ', get_amounts_out[1])


# approve из контракта wbnb
nonce = w3.eth.getTransactionCount(bot_address)
approve_tx_hash, approve_tx_status = approve_function(
    token_contract=wbnb_token_contract,
    router_address=router_contract.address,
    approve_value=get_amounts_out[0],
    nonce=nonce
)
print('approve tx hash: ', approve_tx_hash)
print('approve_tx_status: ', approve_tx_status)

## approve из контракта токена
nonce = w3.eth.getTransactionCount(bot_address)

approve_tx_hash, approve_tx_status = approve_function(
    token_contract=main_token_contract,
    router_address=router_contract.address,
    approve_value=get_amounts_out[1],
    nonce=nonce
)
print('approve tx hash: ', approve_tx_hash)
print('approve_tx_status: ', approve_tx_status)


# test swap exact eth
nonce = w3.eth.getTransactionCount(bot_address)
gas_price = value_based_gas_price_strategy(value)
swap_tx_hash, swap_tx_status = swap_exact_eth(
    router_contract_sample=router_contract,
    token_contract=main_token_contract,
    amount_out_min=get_amounts_out[1],
    path=[wbnb_token_contract.address, main_token_contract.address],
    to=bot_address,
    deadline=w3.eth.getBlock('latest')['timestamp'] + 1000000000,
    gas=gas,
    gas_price=gas_price + 10,
    nonce=nonce
)

I receive this error:

raise ContractLogicError(response['error']['message'])
web3.exceptions.ContractLogicError: execution reverted: PancakeRouter: INSUFFICIENT_OUTPUT_AMOUNT

I calculate exact amounts of output tokens via getAmountsOut function, but it does not help me.

Best Answer

When you make a swap, you're likely to get a little less than the expected amount ( if other people sell/buy while your tx is being processed the price will be different that the one calculated by getAmountsOut(), that's called slippage, you probably already heard the word). If you're doing this as a test project i suggest setting minAmountOut to 0, if you're going to use this to actually sell/buy big amount of tokens, id calculate an acceptable slippage (maybe 1 or 2%) percentage and i'll use this