I have been getting this error for a couple of days. I am trying to calculate the necessary Slippage in PancakeSweap automatically.
For this I am trying different percentages and I call estimateGas to see if the transaction fails. But I only get the error
TransferHelper: TRANSFER_FROM_FAILED
I have tried a lot of methods and none of them work for me.
I'm sure the contract is approved and that it should work in the blockchain side. In pancakeswap it works for me, same wallet, same tokens and same amounts. I do not understand that it can fail.
const Web3 = require("web3");
const abi = require("./abi.json");
const web3 = new Web3("https://bsc-dataseed.binance.org/");
const contract = new web3.eth.Contract(abi, "0x10ed43c718714eb63d5aa57b78b54704e256024e");
function isValid(res) {
return new Promise((resolve, reject) => {
contract.methods.swapExactTokensForTokens(res[0], res[1], ["TOKEN_A", "TOKEN_B" ], "MI_WALLET", 1639969436 ).estimateGas(function(error, result) {
console.log(error.message)
if(error.message.includes("INSUFFICIENT_OUTPUT_AMOUNT")) {
console.log("Bad slippage")
reject()
}
else if(error) {
reject()
}
else {
resolve()
}
});
})
}
(async () => {
contract.methods.getAmountsOut("20000000000", ["TOKEN_A", "TOKEN_B" ]).call().then(async res => {
const data = res;
let slippage = 0;
while (true) {
try {
await isValid(data);
break;
}
catch(e) {
slippage++;
console.log(slippage / 100 * data[1])
let newS = data[1] - (slippage / 100 * data[1])
console.log(slippage, newS);
if(slippage == 20) {
break;
}
}
}
console.log(slippage)
})
})();
Related
I'm making a scraper that will grab every Uniswap pair and save it to an array using the Graph API.
My problem occurs when I make my 7th request to the API.
Initially, I thought I was being rate limited because I was fetching 1000 tokens at a time, but after adding a 10 second wait between calls and decreasing the fetched tokens from 1000 to 10, it still stops on the 7th loop.
The script works perfectly until this point.
const axios = require('axios');
const fs = require('fs');
async function getTokens(skip) {
try {
const query = `
query tokens($skip: Int!) {
tokens(first: 10, skip: $skip) {
id
name
symbol
}
}
`;
const variables = {
skip: skip
};
const headers = {
"Content-Type": "application/json"
};
const { data } = await axios.post("https://api.thegraph.com/subgraphs/name/uniswap/uniswap-v3", {
query,
variables
}, {
headers
});
return data.data.tokens;
} catch (err) {
console.error(err);
return []
}
}
async function saveTokens(tokens) {
try {
await fs.promises.writeFile("uniTokens.json", JSON.stringify(tokens), { flag: "w" });
} catch (err) {
console.error(err);
}
}
async function main() {
let skip = 0;
let tokens = [];
const retrievedIds = new Set();
while (true) {
const newTokens = await getTokens(skip);
if (newTokens.length === 0) {
console.log("Reached end of tokens, finishing up...");
break;
}
// Only save tokens that haven't been retrieved before
const newIds = new Set(newTokens.map(token => token.id));
newIds.forEach(id => {
if (!retrievedIds.has(id)) {
tokens.push(newTokens.find(token => token.id === id));
retrievedIds.add(id);
}
});
console.log(`Retrieved ${tokens.length} tokens`);
await saveTokens(tokens);
skip += 1000;
// delay the next request by 10 seconds
//await new Promise(resolve => setTimeout(resolve, 10000));
}
}
main();
This is the error that it produces:
TypeError: Cannot read properties of undefined (reading 'tokens')
at getTokens (/root/unipairs/uni:31:26)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async main (/root/unipairs/uni:52:27)
Reached end of tokens, finishing up...
I want to save my posts to IndexDB and on client side to list posts even when user offline.
import { openDB } from 'idb'
const dbPromise = () => {
if (!('indexedDB' in window)) {
throw new Error('Browser does not support IndexedDB')
}
return openDB('OfflineDb', 1, upgradeDb => {
if (!upgradeDb.objectStoreNames.contains('posts')) {
upgradeDb.createObjectStore('posts')
}
})
}
const saveToStorage = async (storeName, datas) => {
try {
const db = await dbPromise()
const tx = db.transaction(storeName, 'readwrite')
const store = tx.objectStore(storeName)
store.put(datas, storeName)
return tx.complete
} catch (error) {
return error
}
}
const checkStorage = async storeName => {
try {
const db = await dbPromise()
const tx = db.transaction(storeName, 'readonly')
const store = tx.objectStore(storeName)
return store.get(storeName)
} catch (error) {
return error
}
}
export default {
checkStorage,
saveToStorage
}
Here is my service. When I try to get data;
dbService.checkStorage('posts')
I'm getting error;
DOMException: Failed to execute 'transaction' on 'IDBDatabase': One of the specified object stores was not found.
Why that's happening? I found some solutions but any of them can not solve my problem
I am making a react app and I need to make it so that the user can log in through the Tron Link browser extension. Now it turned out only to connect the application to the wallet, but now I need to install a new state after the connection. But after the execution of the extension call function, the state changes immediately, without waiting for the connection in the extension to complete.
How can I track if the connection is completed in the extension, and if completed, then change the state?
const getAccount = async () => {
if (window.tronWeb !== undefined) {
if (window.tronWeb.defaultAddress.base58) {
try {
setInstallFlag(true);
setlogInFlag(true);
setAddress(window.tronWeb.defaultAddress.base58); //TR9o7SXc9KqPrAxuBVb1gHMCykybxTK3GR
let instance = await window.tronWeb
.contract()
.at("TAx8Jq65YhvXc5saxFsqfLzKEwbQ1EdK64");
setContract(instance);
const account = await window.tronWeb.trx.getAccount(
window.tronWeb.defaultAddress.base58
);
if (account.assetV2) {
const temBal = account.assetV2.find(
(asset) => asset.key === "1002357"
);
if (temBal) {
setAccountBal(temBal.value / 100);
} else {
setAccountBal(0);
}
} else {
setAccountBal(0);
}
let bal = await instance
.balanceOf(window.tronWeb.defaultAddress.base58)
.call();
setBalance(bal.toNumber() / 100);
let prof = await instance
.rewardscheck(window.tronWeb.defaultAddress.base58)
.call();
setProfit(prof.toNumber() / 100);
let clamt = await instance.checkClaim().call();
setClaim(clamt.toNumber() / 100);
} catch (error) {
const msg = error.message ? error.message : error;
}
} else {
setInstallFlag(true);
setlogInFlag(false);
}
} else {
setInstallFlag(false);
setlogInFlag(false);
}
};
const login = () => {
getAccount();
setState('logged');
}
I'm having a problem executing my smart contract. From the error code, I figured it is must be a gas limit problem, although I don't know where I would place the code in order for it to execute properly. Any suggestions?
Solidity code:
pragma solidity ^0.8.0;
import 'hardhat/console.sol';
contract WavePort {
//TrackWaves
uint totalWaves; //State Variable, Permanetly Stored In Contract Storage
constructor() {
console.log("Yo, I am I contract");
}
//Function Increments Waves On The Blockchain/ Immutable Never Decreasing
function wave() public {
totalWaves += 1;
console.log("%s has waved!", msg.sender);
}
//Function Returns Us the The Total Waves To Be Viewed
function getTotalWaves()public view returns(uint256) {
console.log("We have %d total waves", totalWaves);
return totalWaves;
}
}
JavaScript code:
const App = () => {
const [currentAccount, setCurrentAccount] = useState("")
const contractAddress = "contractAddress"
const contractABI = abi.abi
const checkIfWalletConnected = async () => {
let web3
try {
const {ethereum} = window;
if(!ethereum) {
window.alert("Make sure you have metamask !");
return;
}else {
web3 = new Web3(window.ethereum)
console.log("We have the ethereum object", ethereum)}
const accounts = await ethereum.request({method: 'eth_accounts'})
if(accounts.length !== 0) {
const account = accounts[0]
console.log("Found an Authorized account:", account, );
setCurrentAccount(account)
} else {
window.alert("NO authorized account found")
}
const EthBalance = await web3.eth.getBalance(accounts[0])
console.log(EthBalance)
}catch(err) {console.log(err)}
}
const connectWallet = async () => {
try {
const {ethereum} = window;
if(!ethereum) {alert("Get Metamask extenstion")
return
} else {
const accounts = await ethereum.request({method: 'eth_accounts'})
console.log("Connected", accounts[0])
window.alert("Wallet is Connected")
setCurrentAccount(accounts[0])
const ethBlance = await Web3.eth.getBalance(currentAccount)
console.log(ethBlance)
}
}catch(err) {
console.log(err)
}
}
const wave = async () => {
try {
const {ethereum} = window;
if(ethereum) {
const provider = new ethers.providers.Web3Provider(ethereum);
const signer = provider.getSigner();
const wavePortalContract = new ethers.Contract(contractAddress, contractABI, signer);
let count = await wavePortalContract.getTotalWaves( );
const waveTxn = await wavePortalContract.wave({gas:10000000 }, {gasPrice:80000000000});
console.log("Mining....", waveTxn.hash)
await waveTxn.wait( );
console.log("Mined-- ", waveTxn.hash)
count = await await wavePortalContract.getTotalWaves( );
console.log("Retrieved total wave count.. ", count.toNumber())
}else {
console.log("Eth Object doesn't exist!")
}
} catch(err) {console.log(`${err} hello world`) }
}
useEffect(() => {
checkIfWalletConnected();
}, [])
The error code I get:
Error: cannot estimate gas; transaction may fail or may require manual gas limit (error={"code":-32000,"message":"execution reverted"}, method="call", transaction={"from":"0xD49a9a33F180D1e35A30F0ae2Dbfe5716a740Ebc","to":"0x5FbDB2315678afecb367f032d93F642f64180aa3","data":"0x9a2cdc08","accessList":null}, code=UNPREDICTABLE_GAS_LIMIT, version=providers/5.5.1)
While calling a contract Abi method, you can pass an object of additional gas-related params in the second argument (or first if you don't have any arguments in your method).
So calling of wave function should looks like following:
const waveTxn = await wavePortalContract.wave({gasLimit:30000});
Check all additional params in the below documentation.
https://docs.ethers.io/v5/api/contract/contract/#contract-functionsSend
First time using stackoverflow. It is a bot made to post result whenever new episode of show in search list gets added on nyaa.si. I want bot to post result only once for every episode but bot post same episode multiple time in different time frames. It gets fixed for while after I restart the bot.
The code to add show to search list.
async addShow(msg) {
const regex = /"(.+?)" "(.+?)"(?: "(.+?)")?/g;
const found = regex.exec(msg.content);
if (found === null) {
await msg.channel.send(`Invalid new syntax:\n${COMMAND_CHARACTER} new \"show search phrase\" \"MALURL\" \"attribute regex\" (optional last)`);
return;
}
let [f, search, url, reg] = found;
let count = await this.db.get('search').last().value();
if (_.isUndefined(count)) {
count = 0;
}
else {
count = count.id;
}
await this.db.get('search').push({id: count + 1, search, url, regex: reg}).write();
logger.info(`New show has been added to the searchlist - ${search} - ${url} for server ${this.guildID}`);
await msg.channel.send("Saved!");
}
The code to search
async searchShow(id, query, channel = null, OG = null) {
const results = await this.nyaa.getResults(query);
if (!results.length) {
return;
}
logger.info(`Results found for ${query}: ${results.length}`);
const embedFunction = this.getRichEmbed.bind(this);
for (let i of results) {
const item = await this.db.get('rss').find({guid: i.guid}).value();
if (!_.isUndefined(item)) {
continue;
}
if (await this.postShow(embedFunction, i, channel, OG)) {
await this.db.get('rss').push({...i, searchID: id}).write();
}
}
}
Code to post result when new episode comes.
async postShow(embedFunc, item, channel = null, og = null, channelType = NYAA_UPDATES) {
if (channel === null) {
channel = await this.getGuildChannel(channelType);
if (!channel) {
return false;
}
}
return new Promise(async (resolve) => {
const title = (og !== null ? og.title ?? item.title : item.title);
const embed = await embedFunc(item, title);
if (og !== null) {
const img = og.image ?? null;
if (img) {
embed.setThumbnail(img);
}
const url = og.url ?? null;
if (url) {
embed.setURL(url);
}
}
let retryCounter = 0;
logger.info(`Posting new result for ${title} with guid ${item.guid} for server ${this.guildID}`);
while (true) {
try {
await channel.send(embed);
setTimeout(() => {
resolve(true);
}, 2000);
break;
}
catch (e) {
logger.warn(`An error has occured while posting: ${e.toString()}, retrying (${++retryCounter} in 5 seconds`);
await new Promise((res) => {
setTimeout(() => {
res();
}, 5000);
});
if (retryCounter > 10) {
resolve(false);
}
}
}
});
}
Also one who wrote most of code was different person and I only added few additional function here and there which doesn't affect the code much. One who wrote most of core code had to leave discord so I was left to host the bot which I am hosting at repl.it. It will be great help to know whether the problem is with the code or not.
As Julian Kleine mentioned above, the most common reason a bot posts multiple times is if you are running multiple instances of the host. Close all instances of command prompt, and check task manager to see if any other hidden instances are running in the background.