Open marcichan opened 3 years ago
I will upload a sell example Tomorrow. Regards
I have uploaded the sell script: https://github.com/religion-counter/onlyone/blob/main/helper-scripts/sell-onlyone-pancakeswap.js In order to sell you need to first approve the token for selling. This is the approve transaction executed by the script: https://bscscan.com/tx/0x5c87de77a431ced21532d1f10512d0cfd3ec4871f37effb83f62d6e6cd341772 And this is the actual sell again executed by the script: https://bscscan.com/tx/0x7faa7289646526a33e5ee5b46d4cb228d1aca87ec174c7c65679f9c43e2ecb3c I also did many failed attempts like here: https://bscscan.com/tx/0x68df97ff5e9b17566d0dd5345558979609ddc55bfd71a0c494741ac870040307 and this address: https://bscscan.com/address/0xD41FeE0d3f057C01F831ECf31ddC9ef082ADe078 because I tried to sell without approving first :)
Thank you alot! I was able to get it done late in the night, too :D
I am glad to hear that you were able to get it done. Our mission is to educate more people about what is going on behind the crypto scene ;).
Do you know what's the problem with this error? https://bscscan.com/tx/0x7158bb87094da67e90c0afe934b36a7bed37c0085925d01790f46556b1bb91b7
You have to see whether the token you are trying to sell is approved for sell on the router. Also you can try to manually sell via the pancakeswap website and then copy the same transaction data.
I have an error when selling. Amount as in your example. (node:19916) UnhandledPromiseRejectionWarning: Error: Transaction has been reverted by the EVM:
approve: https://bscscan.com/tx/0x39968ba83f35b2efaa654542e6695d7f9d50f6173b8dcb3b5e932c34ed6223b8 sell: https://bscscan.com/tx/0xfe25959a337bc31d4d0900cd055db2b6cda7a2cde4557c8225d224b4e0d0a3ab
Besides that, I have problems:
There are no problems with the purchase. Thanks for your script.
I have an error when selling. Amount as in your example. (node:19916) UnhandledPromiseRejectionWarning: Error: Transaction has been reverted by the EVM:
approve: https://bscscan.com/tx/0x39968ba83f35b2efaa654542e6695d7f9d50f6173b8dcb3b5e932c34ed6223b8 sell: https://bscscan.com/tx/0xfe25959a337bc31d4d0900cd055db2b6cda7a2cde4557c8225d224b4e0d0a3ab
Besides that, I have problems:
* how to determine the balance of a coin. In the wallet of coins: 150382.500540337410654784. The script outputs 150382500540337410654784. I don't understand how to format. * how to correctly transfer the balance of the coin to the sale method
There are no problems with the purchase. Thanks for your script.
Hi sircovsw,
The balance is the number of coins multiplied by the number of decimals. For your use case 150382.500540337410654784 has 18 decimals. For your example (https://bscscan.com/tx/0xfe25959a337bc31d4d0900cd055db2b6cda7a2cde4557c8225d224b4e0d0a3ab) you have input 10000000000 UDOGE and want to receive 5400000000000 BNB for that. You can try to set amountOutMin to 10 or something small (which is something like sell on market price) and see whether the transaction will succeed then.
With the following script I was able to sell UDOGE for ONLYONE: https://bscscan.com/tx/0xa1695466014badc14265c577d5310cf2bd9c59a411d8930659d42cae6c9751c5
Please note that if you want to swap tokens for BNB you should call swapExactTokensForETHSupportingFeeOnTransferTokens
and if you want to swap tokens for other tokens you should call swapExactTokensForTokensSupportingFeeOnTransferTokens
Note that UDOGE gas 9 decimals so I multiply the original amount by 1e9: amountToSell*1e9
// Sells UDOGE for ONLYONE from pancakeswap for address ${targetAccounts[targetIndex].address}
var fs = require('fs')
var Tx = require('ethereumjs-tx').Transaction;
var Web3 = require('web3')
var Common = require('ethereumjs-common').default;
var web3 = new Web3(new Web3.providers.HttpProvider('https://bsc-dataseed.binance.org/'))
var BSC_FORK = Common.forCustomChain(
'mainnet',
{
name: 'Binance Smart Chain Mainnet',
networkId: 56,
chainId: 56,
url: 'https://bsc-dataseed.binance.org/'
},
'istanbul',
);
var targetAccounts = JSON.parse(fs.readFileSync('account-sell-udoge.json', 'utf-8'));
sellMulty();
async function sellMulty() {
for (var i = 0; i < 1; ++i) {
var targetAccount = targetAccounts[i];
var amountToSell = 300012754.293006283; // Amount you want to sell
var res = sell(targetAccount, amountToSell*1e9)
.catch(e => {
console.error("Error in sell:", e);
process.exit(1);
});
console.log(res);
}
}
async function sell(targetAccount, amount) {
var amountToSell = web3.utils.toHex(amount);
var privateKey = Buffer.from(targetAccount.privateKey.slice(2), 'hex') ;
var tokenAddress = '0xd2618bc9c9cdc40ff19e200a7d14a09799c0a152'; // UDOGE contract address
var WBNBAddress = '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'; // WBNB token address
var pancakeSwapRouterAddress = '0x10ed43c718714eb63d5aa57b78b54704e256024e';
var routerAbi = JSON.parse(fs.readFileSync('pancake-router-abi.json', 'utf-8'));
var contract = new web3.eth.Contract(routerAbi, pancakeSwapRouterAddress, {from: targetAccount.address});
var data = contract.methods.swapExactTokensForTokensSupportingFeeOnTransferTokens(
amountToSell,
1,
[tokenAddress,
WBNBAddress,
'0xb899db682e6d6164d885ff67c1e676141deaaa40'
],
targetAccount.address,
web3.utils.toHex(Math.round(Date.now()/1000)+60*20),
);
count = await web3.eth.getTransactionCount(targetAccount.address);
var rawTransaction = {
"from":targetAccount.address,
"gasPrice":web3.utils.toHex(5000000000),
"gasLimit":web3.utils.toHex(460000),
"to":pancakeSwapRouterAddress,
"value":web3.utils.toHex(0),
"data":data.encodeABI(),
"nonce":web3.utils.toHex(count)
};
var transaction = new Tx(rawTransaction, { 'common': BSC_FORK });
transaction.sign(privateKey);
var result = await web3.eth.sendSignedTransaction('0x' + transaction.serialize().toString('hex'));
console.log(result)
return result;
}
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
var amountToSell = 300012754.293006283
Where did you get the value of the variable var amountToSell = 300012754.293006283 ?
Please tell me an example code to get 150382.500540337410654784 from 150382500540337410654784 or 93200875.137806421 from 93200875137806421
Please tell me an example code to get 150382.500540337410654784 from 150382500540337410654784 or 93200875.137806421 from 93200875137806421
Handled it
getTokenBalance = async (tokenAddress) => {
let contractBuyToken = new this.web3.eth.Contract(this.tokenAbi, tokenAddress, {from: this.myContract})
let balance = await contractBuyToken.methods.balanceOf(this.myContract).call()
let tokenDecimals = await this.getTokenDecimals(tokenAddress)
let unit = 'gwei'
if (parseInt(tokenDecimals) === 18) {
unit = 'ether'
}
balance = this.web3.utils.fromWei(balance, unit)
return balance
}
var res = sell(targetAccount, amountToSell*1e9) ... var amountToSell = web3.utils.toHex(amount);
if tokenDecimals is 18, then it does not work:
Error: Error: [number-to-bn] while converting number 1.5038250054033741e+23 to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported. Given value: "1.5038250054033741e+23"
let tokenDecimals = await this.getTokenDecimals(tokenAddress)
let unit = 1e9
let unit1 = 'gwei'
if (parseInt(tokenDecimals) === 18) {
unit = 1e18
unit1 = 'ether'
}
amount = amount * unit;
console.log(Math.floor(Date.now() / 1000), ' - ', 'amount', amount)
let amountToSell = this.web3.utils.toHex(amount);
console.log(Math.floor(Date.now() / 1000), ' - ', 'amountToSell', amountToSell)
var res = sell(targetAccount, amountToSell*1e9) ... var amountToSell = web3.utils.toHex(amount);
if tokenDecimals is 18, then it does not work:
Error: Error: [number-to-bn] while converting number 1.5038250054033741e+23 to BN.js instance, error: invalid number value. Value must be an integer, hex string, BN or BigNumber instance. Note, decimals are not supported. Given value: "1.5038250054033741e+23"
let tokenDecimals = await this.getTokenDecimals(tokenAddress) let unit = 1e9 let unit1 = 'gwei' if (parseInt(tokenDecimals) === 18) { unit = 1e18 unit1 = 'ether' } amount = amount * unit; console.log(Math.floor(Date.now() / 1000), ' - ', 'amount', amount) let amountToSell = this.web3.utils.toHex(amount); console.log(Math.floor(Date.now() / 1000), ' - ', 'amountToSell', amountToSell)
The token decimals are just for human readability. You can just multiply the number of tokens times 10 to the power of the token decimals. So for 1.5038250054033741e+23, e+23 means times 10 to the power of 23 so it equals 150382500540337410000000 and you can use this number.
I am using swapExactTokensForETHSupportingFeeOnTransferTokens. Not working yet. The reason is apparently amountOutMin (https://bscscan.com/tx/0xce521e1371df7e3c4e462ef9563a6f255209e479d0bc350bd0dbaa5ffb1f130f). I'm trying to sell 0.001 BNB. I will try to figure it out. Thank you.
I am using swapExactTokensForETHSupportingFeeOnTransferTokens. Not working yet. The reason is apparently amountOutMin (https://bscscan.com/tx/0xce521e1371df7e3c4e462ef9563a6f255209e479d0bc350bd0dbaa5ffb1f130f). I'm trying to sell 0.001 BNB. I will try to figure it out. Thank you.
Note that UDOGE that you try to sell has very high fees - liquidity fee 10% and tax fee 1% (https://bscscan.com/address/0xd2618bc9c9cdc40ff19e200a7d14a09799c0a152#code) so you won't be able to sell your whole balance. You can try to sell first 50% and see if it works and then sell other part. I was able to sell some UDOGE with the above script but it wasn't 100% of my holdings.
Tell me another such moment, please. How to programmatically find out by token
Or is it not possible and all the information after the purchase of the token needs to be stored in my database?
Tell me another such moment, please. How to programmatically find out by token
* at what price did I buy it * when I bought it * what is my profit or loss now
Or is it not possible and all the information after the purchase of the token needs to be stored in my database?
It is possible but not very easy. You can check https://bscscan.com/apis#tokens for APIs that rely on the bscscan database. From there you can check for your account the transactions for the given token. From the transaction you can check the buying price. There are some limitations because the search for the transactions goes through the blockchain blocks. Also you can use the pancakeswap APIs https://github.com/pancakeswap/pancake-info-api/blob/develop/v2-documentation.md to get the current price.
Yes, not trivial. Thanks.
Hi With the script i was able to perform all buy transaction but in case of sell not all transaction are executed Sell Transaction executed: approve --https://bscscan.com/tx/0x0d0a71ad59f2a034587862c9c5e4397d69e1caae5fa033ab24c9ec63564019db sell--https://bscscan.com/tx/0xc66f7a7a2ae346ecdd64d4453030ea15061992df4f0d4eeaf5a8691f0917b8ae
Sell Transaction Failed: approve -- https://bscscan.com/tx/0x7a6c23b1e976a2fa171494fe52bbf24c88db765abc093531a312b38c4b48844d Sell --- https://bscscan.com/tx/0x3b926ccc90c8af07813710838fa5ce9a6243a44f61b5eaf3db8a8f09e5992019
Both Token are 18 decimal, gas i have increased
Please tell what's the issue?
Hi With the script i was able to perform all buy transaction but in case of sell not all transaction are executed Sell Transaction executed: approve --https://bscscan.com/tx/0x0d0a71ad59f2a034587862c9c5e4397d69e1caae5fa033ab24c9ec63564019db sell--https://bscscan.com/tx/0xc66f7a7a2ae346ecdd64d4453030ea15061992df4f0d4eeaf5a8691f0917b8ae
Sell Transaction Failed: approve -- https://bscscan.com/tx/0x7a6c23b1e976a2fa171494fe52bbf24c88db765abc093531a312b38c4b48844d Sell --- https://bscscan.com/tx/0x3b926ccc90c8af07813710838fa5ce9a6243a44f61b5eaf3db8a8f09e5992019
Both Token are 18 decimal, gas i have increased
Please tell what's the issue?
Can you please try to sell from pancakeswap.finance and then with the script and show the two transactions. There should be some differences. Do you have enough balance? Maybe something with the token or the pair. Maybe the token supports other methods, etc.
Hi,
Thank you for helper scripts!
I'm trying swap B-Token for BNB using swapExactTokensForETH on Pancakeswap Router V2
I've also tried swapExactTokensForETHSupportingFeeOnTransferTokens without and success.
It fails with TransferHelper: TRANSFER_FROM_FAILED
When I use pancakeswap.fiance and metamask it works as in this transaction https://bscscan.com/tx/0x76906d7733566ad9a020994dad44ac7cdddbf5c8d513c769488ae0d9ed96824a
However it fails when I call it from the nodejs script.
https://gist.github.com/tuncatunc/92a827da7e09f7cc9db131a326f96fc5
// Sells B for BNB from pancakeswap for address ${targetAccounts[targetIndex].address}
var fs = require('fs')
var Tx = require('ethereumjs-tx').Transaction;
var Web3 = require('web3')
var Common = require('ethereumjs-common').default;
const ankrlRpcUrl = 'https://rpc.ankr.com/bsc/';
var web3 = new Web3(new Web3.providers.HttpProvider(ankrlRpcUrl))
var BSC_FORK = Common.forCustomChain(
'mainnet',
{
name: 'Binance Smart Chain Mainnet',
networkId: 56,
chainId: 56,
url: ankrlRpcUrl
},
'istanbul',
);
var targetAccounts = [
{
"i": 0,
"address": "0x9d2AC5E8A1460204D05F035ce92892fd86C489C2",
"privateKey": "reducted"
},
]
sellMulty();
async function sellMulty() {
for (var i = 0; i < 1; i++) {
var targetAccount = targetAccounts[i];
var bAmount = 10000000; // Amount you want to sell
const bAmountInWei = web3.utils.toWei(bAmount.toString(), 'ether')
console.log(`${i}: Selling ${bAmount} B for BNB to pancakeswap for address ${targetAccount.address}`);
var res = sellB(targetAccount, bAmountInWei)
.catch(e => {
console.error("Error in sell:", e);
process.exit(1);
});
console.log(res);
await sleep(5000 + Math.random().toFixed(4) * 10000);
}
}
async function sellB(targetAccount, amount) {
var amountToSell = web3.utils.toHex(amount);
var privateKey = Buffer.from(targetAccount.privateKey.slice(2), 'hex');
var abiArray = JSON.parse(JSON.parse(fs.readFileSync('beast-abi.json', 'utf-8')));
var tokenAddress = '0xD96710E8419242A14D59Fe0295B0144aF66fB983'; // B contract address
var WBNBAddress = '0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c'; // WBNB token address
var pancakeSwapRouterAddress = '0x10ed43c718714eb63d5aa57b78b54704e256024e';
// Approve B spend
var bContract = new web3.eth.Contract(abiArray, tokenAddress, { from: targetAccount.address });
var approveBSpendData = bContract.methods.approve(pancakeSwapRouterAddress, web3.utils.toWei('1', 'ether'));
var count = await web3.eth.getTransactionCount(targetAccount.address, 'pending');
var rawTransactionApprove = {
"from": targetAccount.address,
"gasPrice": web3.utils.toHex(5000000000),
"gasLimit": web3.utils.toHex(210000),
"to": tokenAddress,
"value": "0x0",
"data": approveBSpendData.encodeABI(),
"nonce": web3.utils.toHex(count)
};
var transactionApprove = new Tx(rawTransactionApprove, { 'common': BSC_FORK });
transactionApprove.sign(privateKey)
var resultApprove = await web3.eth.sendSignedTransaction('0x' + transactionApprove.serialize().toString('hex'));
console.log("Approved" + resultApprove);
var amountOutMin = 0; // Allow any slippage
var routerAbi = JSON.parse(fs.readFileSync('pancake-router-abi.json', 'utf-8'));
var contract = new web3.eth.Contract(routerAbi, pancakeSwapRouterAddress, { from: targetAccount.address });
// var data = contract.methods.swapExactTokensForETHSupportingFeeOnTransferTokens(
// amountToSell,
// amountOutMin,
// [tokenAddress,
// '0xe9e7cea3dedca5984780bafc599bd69add087d56' /* BUSD address */, // Add this if you want to go through the onlyone-busd pair
// WBNBAddress],
// targetAccount.address,
// web3.utils.toHex(Math.round(Date.now()/1000)+60*20),
// );
var data = contract.methods.swapExactTokensForETH(
amountToSell,
amountOutMin,
[tokenAddress,
WBNBAddress],
targetAccount.address,
web3.utils.toHex(Math.round(Date.now() / 1000) + 60 * 20),
);
count = await web3.eth.getTransactionCount(targetAccount.address);
var rawTransaction = {
"from": targetAccount.address,
"gasPrice": web3.utils.toHex(5000000000),
"gasLimit": web3.utils.toHex(190830),
"to": pancakeSwapRouterAddress,
"value": web3.utils.toHex(0),
"data": data.encodeABI(),
"nonce": web3.utils.toHex(count)
};
var transaction = new Tx(rawTransaction, { 'common': BSC_FORK });
transaction.sign(privateKey);
var result = await web3.eth.sendSignedTransaction('0x' + transaction.serialize().toString('hex'));
console.log(result)
return result;
}
function sleep(ms) {
return new Promise((resolve) => {
setTimeout(resolve, ms);
});
}
I'd really appreciate any help here.
Hi @tuncatunc, Are you sure that the input account: 0x9d2ac5e8a1460204d05f035ce92892fd86c489c2 has enough tokens to sell. Here is the difference: failed transaction:
Function: swapExactTokensForETH(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline)
MethodID: 0x18cbafe5
[0]: 000000000000000000000000000000000000000000084595161401484a000000
[1]: 0000000000000000000000000000000000000000000000000000000000000000
[2]: 00000000000000000000000000000000000000000000000000000000000000a0
[3]: 0000000000000000000000009d2ac5e8a1460204d05f035ce92892fd86c489c2
[4]: 0000000000000000000000000000000000000000000000000000000062e20c92
[5]: 0000000000000000000000000000000000000000000000000000000000000002
[6]: 000000000000000000000000d96710e8419242a14d59fe0295b0144af66fb983
[7]: 000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
successful transaction:
Function: swapExactTokensForETH(uint256 amountIn, uint256 amountOutMin, address[] path, address to, uint256 deadline)
MethodID: 0x18cbafe5
[0]: 000000000000000000000000000000000000000001fe861da2aaf95889340152
[1]: 0000000000000000000000000000000000000000000000000011a76a21e891c0
[2]: 00000000000000000000000000000000000000000000000000000000000000a0
[3]: 000000000000000000000000e718ee70cab22b3795fa8f70d1062336e1576e42
[4]: 0000000000000000000000000000000000000000000000000000000062e16c55
[5]: 0000000000000000000000000000000000000000000000000000000000000002
[6]: 000000000000000000000000d96710e8419242a14d59fe0295b0144af66fb983
[7]: 000000000000000000000000bb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c
The only difference the input address. Can you try with the same address from pancakeswap UI?
Hi @religion-counter 0x9d2ac5e8a1460204d05f035ce92892fd86c489c2 has 614,841,973.007550937535721589 BEAST
I'm trying to sell 10000000 beasts. I convert it to Wei
var bAmount = 10000000; // Amount you want to sell const bAmountInWei = web3.utils.toWei(bAmount.toString(), 'ether')
Hi @religion-counter 0x9d2ac5e8a1460204d05f035ce92892fd86c489c2 has 614,841,973.007550937535721589 BEAST
I'm trying to sell 10000000 beasts. I convert it to Wei
var bAmount = 10000000; // Amount you want to sell const bAmountInWei = web3.utils.toWei(bAmount.toString(), 'ether')
Can you try first sell half of the tokens through pancakeswap.finance and then copy the transaction with the script and execute it. The script is trying to simulate real transactions from the UI. There is some difference in your use case. Is the token approved?
I tried 314841973 Beast token -> BNB swap.
Only [1] is different. It is the amountOutMin
parameter.
I did set it to 0
to allow any slippage amount. That was my fault.
Then I set the amountOutMin
to value from the pancakeswap UI.
The transaction is now success.
Here is successful transaction https://bscscan.com/tx/0xac9bf96ace05b8e23d5c3406c835c72ab433c265d09da8b94a4e0ddb46e8b224
Thank you a lot for pointing out the Input Data differences.
🎉
EDIT: The problem is now how to calculate amountOutMin, the amountOut * 0.95 from getAmountsOut
still causes the swap fail.
It is strange, before with other tokens with 0 amountOutMin it worked. But maybe something in the newer versions of pancakeswap. You can check https://docs.uniswap.org/sdk/2.0.0/guides/pricing for price apis, also you can get the amount of token and bnb for example in the pair contract and divide the token to bnb to get the current price. Glad to hear that now it works but about the price, yes.. Have you tried with other token?
It only works if I get the amountOutMin
parameter from pancakeswap ui.
I’ll be digging more. The pricing api getAmountsOut
doesn’t give me the correct values too.
I’ll be digging more
Good luck. Please post if you find a solution. Thanks!
The problem was here
var approveBSpendData = bContract.methods.approve(pancakeSwapRouterAddress, web3.utils.toWei('1', 'ether'));
I only approved pancakeswap to spend 1 B Token, I increased the approved amount and voila!
Hey, I tried your examples for buying tokens on PancakeSwap. Everything works fine. Now Im trying to sell tokens and I cant get it to work. Could you maybe make an example for that too, or give me some tips? Thanks!