1

I'm learning a little about blockchain and there is something i'm stucked with.

I'm working with pairs from BSC network, and I'd like to get some information if the token can be bought and sold before actually making the transaction. For that, I'm trying to execute those transactions without even commiting them to blockchain (to know if the state could be TRANSFER_FROM_FAILED on sell).

As I understood, if I actually execute those transactions without commiting to blockchain, we can get the result of the operations without paying any fee's.

My code is below:

console.log(`Checking for ${address}`);

let contract = new web3.eth.Contract(require('../../../services/pcsAbi'), PANCAKESWAP_ROUTER_ADDRESS);
let tokenContract = new web3.eth.Contract(require('../../../services/abi.json'), address);

// Below are the steps to execute the batch

// First step: Execute a buy for specific token. Since I don't want to send that transaction to blockchain, I'm just calling that function and see its result
const batch = new web3.eth.BatchRequest();
batch.add(
    contract.methods.swapExactETHForTokens(
        web3.utils.toHex(100),
        [WBNB_ADDRESS, address],
        MY_ADDRESS,
        web3.utils.toHex(Math.round(Date.now()/1000)+60*20)
    )
    .call
    .request({
        gasLimit: 10000000,  
        gasPrice: web3.utils.toWei('100', 'Gwei'), 
        value: web3.utils.toWei('1', 'ether'),
        nonce: 0
    }, 'latest', callback)
);

// Second step. Get balance for the token. I was supposed here to get the balance bought above, but anyway it's returning 0 and I don't know why
tokenContract.methods.balanceOf(MY_ADDRESS).call.request({
    gasLimit: 10000000,  
    gasPrice: web3.utils.toWei('100', 'Gwei'), 
    value: web3.utils.toWei('1', 'ether'),
    nonce: 1
}, 'latest', callbackBalance)

// Third step. I tries to sell the token back. If a token is honeypot, it will fail with TRANSFER_FROM_FAILED state or execution reverted.
batch.add(
    contract.methods.swapExactTokensForETH(
        1,
        1,
        // web3.utils.toHex(1),
        // web3.utils.toHex(10),
        [address, WBNB_ADDRESS],
        MY_ADDRESS,
        web3.utils.toHex(Math.round(Date.now()/1000)+60*20)
    )
    .call
    .request({
        gasLimit: 800000,  
        gasPrice: web3.utils.toWei('10', 'Gwei'), 
        value: web3.utils.toWei('1', 'Ether')  
    }, 'latest', callback2)
);

Steps 1 is executed and I get the output (an array of amounts). Step 2 is returning 0 as balance. Step 3 is not even working, it always says execution reverted and I suppose that's because I don't have even tokens for selling!

Thanks for your help!

1
  • I try to do the same think (simulate a buy/sell tx) for checking if contract is honeypot or not. Did you find a solutions ? Oct 20, 2021 at 19:00

2 Answers 2

1

You can use the eth_call RPC method. It calls the contract, executes it in the context of the current state of the blockchain, and returns the value of the contract execution. This method won't return events emitted, but rather only the return value.

But when using call, you won't be able to preserve the state between different invocations. Right after the first step swapExactETHForTokens is done, all the state changes that the transaction might have simulated won't be available to the second step balanceOf. Thats probably why you are getting it as zero balance.

If you want to simulate multiple calls in a single transaction, you can use a milticall function. Here, essentially, you'll use a multicall contract to make multiple calls to your contract, in a single transaction. You can craft the multicall request in such a way that you get all the information you want in the return statement.

You can read more about multicall here.

0

If you write a new contract, you can simulate different code paths in Solidity using unit tests.

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.