-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Set gasLimit and gasPrice on contract transactions #40
Comments
Good point! I need to update the documentation to include details on this. Any contract operation can take in one additional (optional) parameter, which is an object of overrides.
can be called with:
|
Thanks! |
I've added a small example on the contract non-constant function documentation, but in the documentation overhaul, this will need to have it's own section. Thanks! |
Looks like you can also override the ethers.js/src.ts/utils/transaction.ts Lines 224 to 226 in c2ce59f
|
careful while doing math with ether's BigNumber. It can't handle decimals |
Hi, where do I need to add the above in my code to get this to work? but I'm still getting an error Can anyone guide me in the right direction? Thanks |
Hey @williamoc74, if you just want to add a custom gas price and gas limit to your contract transaction: await contract.yourMethod(arg1, arg2, {gasPrice: ethers.utils.parseUnits('100', 'gwei'), gasLimit: 1000000}); You can also see docs. The code from aakilfernandes that you are copying is for using 5 times the existing default gas price as the new default price. |
Hi @zemse Thank you for the reply. I see you said this else where const transactionOptions = {
gasLimit: 6000000,
gasPrice: ethers.utils.parseUnits('1.0', 'gwei')
value: ethers.utils.parseEther('3.0') // adding this should fix
}
So I'm going to try this next. If this doesn't work, can I post my code and hopefully we can find a solution that way?
Again, much thanks.. :) |
No joy with the above - I even remove the "value...." `New pair detected
(node:6337) UnhandledPromiseRejectionWarning: Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"reason":"cannot estimate gas; transaction may fail or may require manual gas limit","code":"UNPREDICTABLE_GAS_LIMIT","error":{"code":3,"response":"{"jsonrpc":"2.0","id":6,"error":{"code":3,"data":` |
Can you include the full error and your current code? If you are passing |
Hi Ricmoo.. This is the code const ethers = require('ethers');
const addresses = {
WETH: '0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2',
factory: '0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f',
router: '0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D',
recipient: '*****'
}
const mnemonic = '*****';
const provider = new ethers.providers.WebSocketProvider('*****');
const wallet = ethers.Wallet.fromMnemonic(mnemonic);
const account = wallet.connect(provider);
const factory = new ethers.Contract(
addresses.factory,
['event PairCreated(address indexed token0, address indexed token1, address pair, uint)'],
account
);
const router = new ethers.Contract(
addresses.router,
[
'function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)',
'function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'
],
account
);
factory.on('PairCreated', async (token0, token1, pairAddress) => {
console.log(`
New pair detected
=================
token0: ${token0}
token1: ${token1}
pairAddress: ${pairAddress}
`);
//The quote currency needs to be WETH (we will pay with WETH)
let tokenIn, tokenOut;
if(token0 === addresses.WETH) {
tokenIn = token0;
tokenOut = token1;
}
if(token1 == addresses.WETH) {
tokenIn = token1;
tokenOut = token0;
}
//The quote currency is not WETH
if(typeof tokenIn === 'undefined') {
return;
}
//We buy for 0.1 ETH of the new token
const amountIn = ethers.utils.parseUnits('0.01', 'ether');
const amounts = await router.getAmountsOut(amountIn, [tokenIn, tokenOut]);
//Our execution price will be a bit different, we need some flexbility
const amountOutMin = amounts[1].sub(amounts[1].div(10));
console.log(`
Buying new token
=================
tokenIn: ${amountIn.toString()} ${tokenIn} (WETH)
tokenOut: ${amountOutMin.toString()} ${tokenOut}
`);
const tx = await router.swapExactTokensForTokens(
amountIn,
amountOutMin,
[tokenIn, tokenOut],
addresses.recipient,
Date.now() + 1000 * 60 * 10 //10 minutes
);
const receipt = await tx.wait();
console.log('Transaction receipt');
console.log(receipt);
}); I've removed all the code if tried to get it to work `New pair detected
(node:11176) UnhandledPromiseRejectionWarning: Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"reason":"cannot estimate gas; transaction may fail or may require manual gas limit","code":"UNPREDICTABLE_GAS_LIMIT","error":{"code":3,"response":"{"jsonrpc":"2.0","id":10,"error":{"code":3,"data":"0x08c379a0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000000000000000000000000000000000000000000245472616e7366657248656c7065723a205452414e534645525f46524f4d5f4641494c454400000000000000000000000000000000000000000000000000000000","message":"execution reverted: TransferHelper: TRANSFER_FROM_FAILED"}}"},"method":"estimateGas","transaction":{"from":"0x6657acbCF04775b8D36Ca0659F08F281f635F538","gasPrice":{"type":"BigNumber","hex":"0x10ff239a00"},"to":"0x7a250d5630B4cF539739dF2C5dAcb4c659F2488D","data":"0x38ed173900000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000004b8df0f1629874700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000006657acbcf04775b8d36ca0659f08f281f635f53800000000000000000000000000000000000000000000000000000179705aaf4d0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ca5574f9064e9fa5bfe638466fe61cd0e265afd4","accessList":null}}, tx={"data":"0x38ed173900000000000000000000000000000000000000000000000000470de4df82000000000000000000000000000000000000000000000000000004b8df0f1629874700000000000000000000000000000000000000000000000000000000000000a00000000000000000000000006657acbcf04775b8d36ca0659f08f281f635f53800000000000000000000000000000000000000000000000000000179705aaf4d0000000000000000000000000000000000000000000000000000000000000002000000000000000000000000c02aaa39b223fe8d0a0e5c4f27ead9083c756cc2000000000000000000000000ca5574f9064e9fa5bfe638466fe61cd0e265afd4","to":{},"from":"0x6657acbCF04775b8D36Ca0659F08F281f635F538","gasPrice":{},"nonce":{},"gasLimit":{},"chainId":{}}, code=UNPREDICTABLE_GAS_LIMIT, version=abstract-signer/5.1.0) Thanks in advance, I appreciate you taking the time.. :) |
You still need to pass the overrides (with |
OK, I've tried what I think you mean(I am a noob here, and I realise this isn't a tutorial type forum for noobs so I do appreciate both of you helping me figure this out :) ) This is the changed code
); and this is a screenshot of the error, the last error I posted looked kind of messy so hopefully a screenshot is better. Thanks again |
Can you recheck if you have 0.001 WETH balance? Also note it's not ETH balance, it's WETH. If you don't have that, you first have to convert your ETH into WETH using the deposit function on WETH contract.
BTW from next time pls copy and paste the text if possible instead of a screenshot. Since it enables someone to copy some addresses/tx hashes from it and debug for you. |
Ah ok - that makes sense, the code i was copying in previous posts seemed messy so thought screenshots were better. WETH balance is there ready to go so currently have enough there.. I have ETH in the wallet for gas and WETH for the swap.. |
Oh, then it should work. Can you give me the tx hash? I can try to see.
You can give this doc a try, and it will be best if you can include the minimal code required to reproduce the problem / show your use case. |
This is the latest failed one.. https://etherscan.io/tx/0xdc1113fd31a0615ec9b7ca045a2672c470d7172922b2a0ff6b370caeadc4c4d9 |
Oh I just checked the trace on tenderly, and from that, it appears that there is no WETH approval to the router contract for spending your WETH. I'd suggest you give the router contract infinite approval ( |
The error on etherscan is just out of gas error. Also |
Okay, I will try that and update :) |
Worked like a charm :) |
Thanks! My address is zemse.eth (0xf51C53b2C184Aa43A7d24aA4f0Cf13D0e8b56c51) |
Tip Sent :) |
Hey George! When you say it doesn't work, what do you mean? Is it giving an error? |
This is the code for bsc. It find new pairs, approves wbnb but doesnt buy the token. const ethers = require('ethers'); const addresses = { } //First address of this mnemonic must have enough BNB to pay for tx fess const provider = new ethers.providers.WebSocketProvider('wss adress'); const wbnb = new ethers.Contract( const init = async () => { factory.on('PairCreated', async (token0, token1, pairAddress) => { //The quote currency needs to be WBNB (we will pay with WBNB) if(token1 == addresses.WBNB) { //The quote currency is not WBNB //We buy for 0.1 BNB of the new token const tx = await router.swapExactTokensForTokens( ); init(); |
Same problem here with BSC. How to setup gasprice and gaslimit? |
Same issue. I run the code, It does not buy tokens. |
Hey @ivekivek, you can refer to #40 (comment) above. Lmk if that doesn't help @George8812 @isaac0310 Can you try the above discussed solutions? Just to summarise:
|
I wanted to try out this bot as well. What should I do about the selling part, should I automate it, and do it immediately after the buy, or wait and then sell ? How many seconds should I wait before the sell ? |
Hey mates! Thanks for your work. I'm trying to make this work for BSC with no luck. I followed @zemse advice and still got errors. My code: const ethers = require('ethers')
const addresses = {
WBNB: '0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c',
factory: '0xcA143Ce32Fe78f1f7019d7d551a6402fC5350c73',
router: '0x10ED43C718714eb63d5aA57B78B54704E256024E',
recipient: '...'
}
const mnemonic = '....'
const pk = '...'
const ws = "wss://bsc-ws-node.nariox.org:443"
const provider = new ethers.providers.WebSocketProvider(ws)
const wallet = new ethers.Wallet(pk)
const account = wallet.connect(provider)
const factory = new ethers.Contract(
addresses.factory,
['event PairCreated(address indexed token0, address indexed token1, address pair, uint)'],
account
)
const router = new ethers.Contract(
addresses.router,
[
'function getAmountsOut(uint amountIn, address[] memory path) public view returns (uint[] memory amounts)',
'function swapExactTokensForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)',
'function swapExactETHForTokens(uint amountIn, uint amountOutMin, address[] calldata path, address to, uint deadline) external returns (uint[] memory amounts)'
],
account
)
const wbnb = new ethers.Contract(
addresses.WBNB,
[
'function approve(address spender, uint amount) public returns(bool)'
],
account
)
const sniper = async () => {
const tx = await wbnb.approve(
router.address,
ethers.constants.MaxUint256
)
const receipt = await tx.wait()
console.log('Transaction receipt')
console.log(receipt)
}
const buy = async (token0: any, token1: any) => {
// The quote currency needs to be WBNB (we will pay with WBNB)
let tokenIn, tokenOut
if(token0 === addresses.WBNB) {
tokenIn = token0
tokenOut = token1
}
if(token1 == addresses.WBNB) {
tokenIn = token1
tokenOut = token0
}
// The quote currency is not WBNB
if(typeof tokenIn === 'undefined') {
return
}
// We buy for 0.002 BNB of the new token
const amountIn = ethers.utils.parseUnits('0.002', 'ether')
const amounts = await router.getAmountsOut(amountIn, [tokenIn, tokenOut])
// Our execution price will be a bit different, we need some flexbility
const amountOutMin = amounts[1].sub(amounts[1].div(10))
console.log(`
Buying new token
=================
tokenIn: ${amountIn.toString()} ${tokenIn} (WBNB)
tokenOut: ${amountOutMin.toString()} ${tokenOut}
`)
const tx = await router.swapExactTokensForTokens(
amountIn,
amountOutMin,
[tokenIn, tokenOut],
addresses.recipient,
Math.floor(Date.now() / 1000) + 60 * 10, // 10 minutes from the current Unix time
{ gasPrice: 5000000000, gasLimit: 1000000 }
)
const receipt = await tx.wait()
console.log('Transaction receipt')
console.log(receipt)
}
factory.on('PairCreated', async (token0: any, token1: any, pairAddress: any) => {
console.log(`
New pair detected
=================
token0: ${token0}
token1: ${token1}
pairAddress: ${pairAddress}
`)
setTimeout(async() => {
await buy(token0, token1)
}, 15000)
}) Error: Thanks for your help! |
Hey guys, if you have a faling transaction, I'd recommend you to check it once on tenderly. It helps you see reason of your transaction failure. In case of @shelkem, you do not have enough WBNB token balance. |
@williamoc74 |
What have you enter here? |
The selling is tricky. To be honest, the bot isn't worth it the way it is, you just end up picking up all the garbage and getting rugged constantly.. I'm trying to get it to run on pancake, I have it detecting them and trying to buy but but it doesn't go through with the transaction. It executes upto this point but doesn't buy - @ricmoo @zemse any ideas? I'm sure it's something simple, it's wrecking me head.. I've tried using 'swapExactETHTokensForTokens' too and still no joy.. |
I may be able to give you a hand with debugging. |
@williamoc74 Can you |
Hi everyone, Previous answers helped a lot but I'm still facing a last one https://dashboard.tenderly.co/tx/bsc/0x50e1f5ac4f1c89efd422814876c7b0a098c25868bc6f94a26446815fd4de9f0b Here are my gas limits settings { gasPrice: 5000000000, gasLimit: 1000000 } and here is the error message: Can someone help please? |
@juloxrox In the tenderly it shows that your tx was failed because there wasn't enough allowance. I wish to see the day when errors in the blockchain ecosystem would become as great as errors spit out by the Rust compiler. |
@zemse Yes this is what I get but I'm wondering why? It's on the contract side right? What does it mean there is no allowance? And what can I do to avoid that? In my approvel function, my allowance for WBNB is set to ethers.constants.MaxUint256 |
What code are you using to execute the transaction here @juloxrox { |
@williamoc74 I'm swappping WBNB for now with those gas settings { gasPrice: 5000000000, gasLimit: 1000000 } |
My wallet private key @George8812 |
Eh eh eh, that's up to you :p |
Thank you Dr Evil : ¬ ) Just seeing if anyone had any tips, but I guess I'll try a few experiments..... |
Be creative! Mu suggestion is to gather some data and make some simulations. |
@zemse thanks for your answers in this thread. Has been helpful. I am getting started with ethers.js and was hoping you could point me in the right direction for working the approve function in. I am honestly not sure where to start here. Basically I am sending the tx but receiving allowance error
I have tried re-working some of the approve functions used here for wbnb but to no avail. Such as:
Using this I end up with an error for:
I can see the function in ERC20 contracts, for the life of me I just can not find similar scripts or guides to draw from. Any help would be appreciated. @williamoc74 if you could share your approve function that would be amazing |
Update to this I think I have it working, or at least I can see txhash is now approving 4 eth.
|
Polygon increased it's minimum gas price from 30 Gwei to 1Gwei to curb spam. Other blockchains might change their default gas price as well so we should get that value from the provider. see: https://medium.com/stakingbits/polygon-minimum-gas-fee-is-now-30-gwei-to-curb-spam-8bd4313c83a2 ethers-io/ethers.js#2828 (comment) ethers-io/ethers.js#40 (comment)
@ricmoo or someone - why would I need to provide gas price or gas limit overrides for an external/view contract function if they don't require gas and are not being performed inside another transaction? And, no other processing is occurring but returning contract state variables. function getDetails() I encountered the "cannot estimate gas; transaction may fail or may require manual gas limit" error originally. It also required that I use a signer and not just a provider when creating the contract instance. To make it worse, once I switched to a signer, and provided those overrides
I receive an insufficient funds error (Rinkeby) when I have .6 ETH on the account: Error: insufficient funds for intrinsic transaction cost [ See: https://links.ethers.org/v5-errors-INSUFFICIENT_FUNDS ] (error={"code":-32000,"message":"err: insufficient funds for gas * price + value: address 0xc0Eb169794B18685a67C0a998292D184Ddeaeba3 have 600000000000000000 want 200000000000000000000000 (supplied gas 500000000)"}, method="call", transaction={"from":"0xc0Eb169794B18685a67C0a998292D184Ddeaeba3","gasLimit":{"type":"BigNumber","hex":"0x058d15e176280000"},"gasPrice":{"type":"BigNumber","hex":"0x016bcc41e90000"},"to":"0x5FbDB2315678afecb367f032d93F642f64180aa3","data":"0x936afab3","accessList":null}, code=INSUFFICIENT_FUNDS, version=providers/5.4.5) |
@hyndsite were you able to sort this out facing a similar issue ? |
A pure or view function (external/public are irrelevant to ethers ABI) do not require gas limit and won’t look it up. Usually this error is caused by forgetting the |
I've been searching in the online documentation for a way to set my gasPrice and gasLimit when creating a transaction on a contract, but couldn't find a way to make it work. I attempted to modify the transaction while signing using a CustomSigner, but didn't had any success.
Is there any way to do it?
The text was updated successfully, but these errors were encountered: