1

So I have recently been using ethers-rs. I was forking mainnet using anvil, and I tried to front run an uniswap v2 swap. Every time I was trying to frontrun the transaction the frontrun swap was failing. But the exact same code was running smoothly when I wasn't trying to frontrun.

Here is the error I was seeing :

 {
        "reason": "invalid codepoint at offset 22; missing continuation byte",
        "code": "INVALID_ARGUMENT",
        "argument": "bytes",
        "value": {
                "0": 0,
                "1": 0,
                "2": 0,
                "3": 0,
                "4": 0,
                "5": 0,
                "6": 0,
                "7": 0,
                "8": 0,
                "9": 0,
                "10": 0,
                "11": 0,
                "12": 0,
                "13": 0,
                "14": 0,
                "15": 0,
                "16": 0,
                "17": 0,
                "18": 0,
                "19": 1,
                "20": 90,
                "21": 241,
                "22": 215,
                "23": 139,
                "24": 88,
                "25": 196,
                "26": 0,
                "27": 0,
                "28": 0,
                "29": 0,
                "30": 0,
                "31": 0,
                "32": 0,
                "33": 0,
                "34": 0,
                "35": 0,
                "36": 0,
                "37": 0,
                "38": 0,
                "39": 0,
                "40": 0,
                "41": 0,
                "42": 0,
                "43": 0,
                "44": 0,
                "45": 0,
                "46": 0,
                "47": 0,
                "48": 0,
                "49": 0,
                "50": 0,
                "51": 0,
                "52": 180,
                "53": 120,
                "54": 1,
                "55": 187,
                "56": 125,
                "57": 252,
                "58": 180,
                "59": 113
        }
}

Here was my swap function:

use std::time::{UNIX_EPOCH, SystemTime};

use ethers_contract::abigen;
use ethers::{
    prelude::{SignerMiddleware, Middleware},
    providers::{Provider, Http},
    types::{Address, TransactionRequest, NameOrAddress, U256, Eip1559TransactionRequest},
    signers::LocalWallet
};

use crate::read_from_root;

pub struct TxGas {
    pub max_priority_fee_per_gas: Option<U256>,
    pub max_fee_per_gas: Option<U256>
}

abigen!(UniswapV2Router02, r"[
    function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline)
    function swapETHForExactTokens(uint256 amountOut, address[] path, address to, uint256 deadline)
]");

pub async fn swap_exact_eth_for_tokens(amount_in: u128, signer: SignerMiddleware<Provider<Http>, LocalWallet>, gas_option: TxGas) {

    let signer_middleware = std::sync::Arc::new(signer);
    let sender_address = signer_middleware.address();

    let uni_v2_router_addr: Address = read_from_root("./contracts/script/state/addresses/uni-v2-router.txt").parse().unwrap();
    let tkn_addr: Address = read_from_root("./contracts/script/state/addresses/token.txt").parse().unwrap();
    let weth_addr: Address = read_from_root("./contracts/script/state/addresses/weth.txt").parse().unwrap();

    let uni_v2_router = UniswapV2Router02::new(uni_v2_router_addr, signer_middleware.clone());

    let mut path = Vec::new();
    path.push(weth_addr);
    path.push(tkn_addr);

    let amount_wei = U256::from(amount_in).checked_mul(U256::from(10_u64.pow(18))).unwrap();

    let tx_data = uni_v2_router.swap_exact_eth_for_tokens(
        (0).into(),
        path,
        sender_address,
        (SystemTime::now().duration_since(UNIX_EPOCH).unwrap().as_secs() * 2).into()
    );
    let tx = Eip1559TransactionRequest {
        from: None,
        to: Some(NameOrAddress::Address(uni_v2_router_addr)),
        value: Some(amount_wei),
        data: Some(tx_data.tx.data().unwrap().clone()),
        max_priority_fee_per_gas: gas_option.max_priority_fee_per_gas,
        max_fee_per_gas: gas_option.max_fee_per_gas,
        ..Default::default()
    };

    let response = signer_middleware.send_transaction(tx, None).await.expect("Failed to send transaction");
    println!("My Swap: {:?}", response);
}

1 Answer 1

1

The error is not very explicit, and the fact that the exact same code was working in one situation but not the other was weird.

The code finally ran when I manually provided a gas amount (gas limit) for the Eip1559TransactionRequest.


    let tx = Eip1559TransactionRequest {
        from: None,
        to: Some(NameOrAddress::Address(uni_v2_router_addr)),
        value: Some(amount_wei),
        data: Some(tx_data.tx.data().unwrap().clone()),
        gas: Some(U256::from(500_000)), // LINE ADDED
        max_priority_fee_per_gas: gas_option.max_priority_fee_per_gas,
        max_fee_per_gas: gas_option.max_fee_per_gas,
        ..Default::default()
    };

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.