-
IssueIf you call one of the contracts write functions you need to pay a gas fee. For example I have some tokens in my wallet which I want to sell. Since there are a lot of scammer I might not be able to sell it (e.g. it's a honey pot contract). To avoid unnecessary gas fees I would like to simulate the contract call and see if it fails. If it succeeds I would execute a real transaction which would also be written to the blockchain. What I already tried
I tried to use
But when I use it to test a function I just get an empty array Questions
Any advice is greatly appreciated! |
Beta Was this translation helpful? Give feedback.
Replies: 6 comments 22 replies
-
I think I just solved it.. I used the PancakeSwap router contract to swap tokens and used If I use |
Beta Was this translation helpful? Give feedback.
-
Hello ysfaran, I'm currently working on the same quastion, to check if the token is sellable and avoid honeypot, but I'm struggling with transaction simulation. Have you been able to make it works ? If yes, is it possible to exchange with you ? Best regards, Mateo |
Beta Was this translation helpful? Give feedback.
-
Hi lidd77, the only solution to your needs is to write a smart contract in
solidity where you'll write a function that buys and sells the token in a
single transaction. Then you can call this function from JS with
CallStatic, avoiding so to make a real purchase. If the token is a
honeypot, the transaction will fail and the JS code will receive an
exception. Hope this helps.
Il giorno lun 23 mag 2022 alle ore 16:18 lidd77 ***@***.***>
ha scritto:
… hello, if I do not have some tokens in my wallet , how to simulate to sell
? callStatic will work for this situation ?
—
Reply to this email directly, view it on GitHub
<#2367 (reply in thread)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/ADAERK3OVTSNFEBASHZVLODVLOHVFANCNFSM5JIMTJMQ>
.
You are receiving this because you commented.Message ID: <ethers-io/ethers
.***@***.***>
|
Beta Was this translation helpful? Give feedback.
-
A service I have not nearly worked with enough, but really want to try out more (and create a custom provider for in v6) is https://tenderly.co. It should allow you to fork and make virtual changes to a blockchain to simulate anything your heart desires. I haven’t used it though and my experience is people whose opinion I deeply value, have raved about it, so any feedback is appreciated. :) |
Beta Was this translation helpful? Give feedback.
-
I'm also looking into this question, however, callStatic only tells you if the transaction will succeed, is there a way to get the simulated output ? |
Beta Was this translation helpful? Give feedback.
-
What about injecting a function using eth_call and performing all the validations? interface IUniSwap {
function swapExactETHForTokens(uint amountOutMin, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts);
function swapTokensForExactETH(uint amountOut, uint amountInMax, address[] calldata path, address to, uint deadline) external payable returns (uint[] memory amounts);
function getAmountsOut(uint amountIn, address[] memory path) external returns (uint[] memory amounts);
}
interface IERC20 {
function deposit() external payable;
function balanceOf(address account) external view returns (uint256);
function transfer(address to, uint256 amount) external returns (bool);
function approve(address spender, uint256 amount) external returns (bool);
}
contract CheckIt {
address constant NICE_TOKEN = 0x53F64bE99Da00fec224EAf9f8ce2012149D2FC88;
address constant WETH_TOKEN = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
address constant NICE_WETH_PAIR = 0x6D5416567E09b99D7B4b7897129Edb19C2F1305A;
function test_transfer_tax() external payable returns(bool) {
address[] memory buyPath = new address[](2);
buyPath[0] = WETH_TOKEN;
buyPath[1] = NICE_TOKEN;
address[] memory sellPath = new address[](2);
sellPath[0] = NICE_TOKEN;
sellPath[1] = WETH_TOKEN;
uint256[] memory buyExpected = IUniSwap(NICE_WETH_PAIR).getAmountsOut(msg.value, buyPath);
IUniSwap(NICE_WETH_PAIR).swapExactETHForTokens{value: msg.value}(0, buyPath, address(this), block.timestamp + 15);
uint256 buyReceived = IERC20(NICE_TOKEN).balanceOf(address(this));
IERC20(NICE_TOKEN).approve(address(this), buyReceived);
uint256[] memory sellExpected = IUniSwap(NICE_WETH_PAIR).getAmountsOut(buyReceived, sellPath);
IUniSwap(NICE_WETH_PAIR).swapTokensForExactETH(0, buyReceived, sellPath, address(this), block.timestamp + 15);
uint256 sellReceived = IERC20(WETH_TOKEN).balanceOf(address(this));
return (buyExpected[1] > buyReceived || sellExpected[1] > sellReceived);
}
} const FAKE_BYTECODE = "0x..."; // Bytecode of contract above in hex
const FAKE_CONTRACT_ADDRESS = "0x6969696969696969696969696969696969696969";
let contract = new ethers.Contract(FAKE_CONTRACT_ADDRESS, [
"function test_transfer_tax() external payable returns(bool)",
provider
;
const functionData = contract.interface.encodeFunctionData("test_transfer_tax");
const result = await provider.send("eth_call", [
{
to: "FAKE_CONTRACT_ADDRESS",
value: ethers.utils.parseEther("1.0").toHexString(),
functionData,
},
"latest",
{
[FAKE_CONTRACT_ADDRESS]: {
code: FAKE_CONTRACT_ADDRESS,
balance: ethers.utils.hexStripZeros(ethers.utils.parseEther("1").toHexString()),
},
},
]); |
Beta Was this translation helpful? Give feedback.
I think I just solved it.. I used the PancakeSwap router contract to swap tokens and used
swapExactTokensForETHSupportingFeeOnTransferTokens
which seems to catch all errors and just handout a[]
in case of failures.If I use
swapExactTokensForETH
it actually works and outputs correct errors withcallStatic
.