Closed VexyCats closed 3 years ago
Please use the latest version of web3.js!
I have the same issue, with version "web3": "^1.3.5"
I'm trying to call a router contract function getAmountOut:
Function ABI:
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
],
name: "getAmountsOut",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "view",
type: "function",
}
In some coins with extremely low value i get the overflow error:
Error: overflow (fault="overflow", operation="toNumber", value="3963877391197344453575983046348115674221700746820753546331534351508065746944", code=NUMERIC_FAULT, version=bignumber/5.1.0)
at Logger.makeError (/home/nico/Documents/bsc/node_modules/@ethersproject/logger/lib/index.js:180:21)
at Logger.throwError (/home/nico/Documents/bsc/node_modules/@ethersproject/logger/lib/index.js:189:20)
at throwFault (/home/nico/Documents/bsc/node_modules/@ethersproject/bignumber/lib/bignumber.js:305:19)
at BigNumber.toNumber (/home/nico/Documents/bsc/node_modules/@ethersproject/bignumber/lib/bignumber.js:153:13)
at /home/nico/Documents/bsc/node_modules/@ethersproject/abi/lib/coders/array.js:90:60
at Array.forEach (<anonymous>)
at Object.unpack (/home/nico/Documents/bsc/node_modules/@ethersproject/abi/lib/coders/array.js:85:12)
at TupleCoder.decode (/home/nico/Documents/bsc/node_modules/@ethersproject/abi/lib/coders/tuple.js:39:49)
at AbiCoder.decode (/home/nico/Documents/bsc/node_modules/@ethersproject/abi/lib/abi-coder.js:93:22)
at ABICoder.decodeParametersWith (/home/nico/Documents/bsc/node_modules/web3-eth-abi/lib/index.js:304:30)
at ABICoder.decodeParameters (/home/nico/Documents/bsc/node_modules/web3-eth-abi/lib/index.js:285:17)
at Contract._decodeMethodReturn (/home/nico/Documents/bsc/node_modules/web3-eth-contract/lib/index.js:470:22)
at Method.outputFormatter (/home/nico/Documents/bsc/node_modules/web3-eth-contract/lib/index.js:760:42)
at Method.formatOutput (/home/nico/Documents/bsc/node_modules/web3-core-method/lib/index.js:147:54)
at sendTxCallback (/home/nico/Documents/bsc/node_modules/web3-core-method/lib/index.js:523:33)
at /home/nico/Documents/bsc/node_modules/web3-core-requestmanager/lib/index.js:308:9
at XMLHttpRequest.request.onreadystatechange (/home/nico/Documents/bsc/node_modules/web3-providers-http/lib/index.js:98:13)
at XMLHttpRequestEventTarget.dispatchEvent (/home/nico/Documents/bsc/node_modules/xhr2-cookies/dist/xml-http-request-event-target.js:34:22)
at XMLHttpRequest._setReadyState (/home/nico/Documents/bsc/node_modules/xhr2-cookies/dist/xml-http-request.js:208:14)
at XMLHttpRequest._onHttpResponseEnd (/home/nico/Documents/bsc/node_modules/xhr2-cookies/dist/xml-http-request.js:318:14)
at IncomingMessage.<anonymous> (/home/nico/Documents/bsc/node_modules/xhr2-cookies/dist/xml-http-request.js:289:61)
at IncomingMessage.emit (events.js:215:7)
at endReadableNT (_stream_readable.js:1183:12)
at processTicksAndRejections (internal/process/task_queues.js:80:21) {
reason: 'overflow',
code: 'NUMERIC_FAULT',
fault: 'overflow',
operation: 'toNumber',
value: '3963877391197344453575983046348115674221700746820753546331534351508065746944'
}
My code:
try {
priceArray = await router.methods.getAmountsOut(1000000000, path).call({});
} catch (error) {
await eventLog(error, CONSTANTS.ERRORS.FETCHING_PRICES);
return undefined;
}
To reproduce:
npm i web3
const Web3 = require("web3");
const web3 = new Web3("https://bsc-dataseed1.binance.org:443");
const ABIRouter = [
{
inputs: [
{ internalType: "uint256", name: "amountIn", type: "uint256" },
{ internalType: "address[]", name: "path", type: "address[]" },
],
name: "getAmountsOut",
outputs: [
{ internalType: "uint256[]", name: "amounts", type: "uint256[]" },
],
stateMutability: "view",
type: "function",
},
];
const router = new web3.eth.Contract(
ABIRouter,
"0x05fF2B0DB69458A0750badebc4f9e13aDd608C7F"
);
const path = [
"0x81e4d494b85a24a58a6ba45c9b418b32a4e039de",
"0xbb4cdb9cbd36b01bd1cbaebf2de08d9173bc095c",
"0xe9e7cea3dedca5984780bafc599bd69add087d56",
];
const test = async () => {
try {
console.log(router.methods);
priceArray = await router.methods.getAmountsOut(1000000000, path).call({});
console.log(priceArray[2].toString()); //if works prints the big number
} catch (error) {
console.log(error); //print the erro
return undefined;
}
};
test();
Edit: I've already tried supplying the function with the number in string, web.BN, BigNumber and Hex
I am having the same problem for a few days with last version of web3.
Duplicated issue? #3897
Bignumbers have been a bit of a bottleneck for us, we are working on this. Thank you for pointing this out.
Because data format when return the result ( normal get symbol() function return string type but some contract return bytes32) .You should handle for each type. Please see attach code .I handle to get symbol data for normal and unnormal contract:
async function getTokenNameBalance (contractAddress, address) { return new Promise(async (resolve, reject) => { const minABI = [{ constant: true, inputs: [], name: 'name', outputs: [{ name: '', type: 'string' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'spender', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'approve', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [{ name: 'value', type: 'uint256' }], name: 'estimateFee', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'totalSupply', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'issuer', outputs: [{ name: '', type: 'address' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'transferFrom', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [], name: 'minFee', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'decimals', outputs: [{ name: '', type: 'uint8' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'value', type: 'uint256' }], name: 'setMinFee', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [{ name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'mint', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [{ name: 'value', type: 'uint256' }], name: 'burn', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [{ name: 'owner', type: 'address' }], name: 'balanceOf', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'symbol', outputs: [{ name: '', type: 'string' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'account', type: 'address' }], name: 'addMinter', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [], name: 'renounceMinter', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [{ name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'transfer', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [{ name: 'account', type: 'address' }], name: 'isMinter', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [{ name: 'owner', type: 'address' }, { name: 'spender', type: 'address' }], name: 'allowance', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { inputs: [], payable: false, stateMutability: 'nonpayable', type: 'constructor' }, { anonymous: false, inputs: [{ indexed: true, name: 'account', type: 'address' }], name: 'MinterAdded', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'account', type: 'address' }], name: 'MinterRemoved', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'from', type: 'address' }, { indexed: true, name: 'to', type: 'address' }, { indexed: false, name: 'value', type: 'uint256' }], name: 'Transfer', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'owner', type: 'address' }, { indexed: true, name: 'spender', type: 'address' }, { indexed: false, name: 'value', type: 'uint256' }], name: 'Approval', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'from', type: 'address' }, { indexed: true, name: 'to', type: 'address' }, { indexed: true, name: 'issuer', type: 'address' }, { indexed: false, name: 'value', type: 'uint256' }], name: 'Fee', type: 'event' }] const contract = new web3.eth.Contract(minABI, contractAddress) contract.methods.name().call().then(name => { contract.methods.symbol().call().then(symbol => { contract.methods.balanceOf(address).call().then(balance => { contract.methods.decimals().call().then(decimal => { resolve({ name: name, symbol: symbol, balance: balance, decimal }) }).catch((e) => { resolve({ name: '', symbol, balance: balance, decimal: 18 }) }) }).catch(err => { // console.log('e1', err) reject(err) }) }).catch(err => { // console.log('e2', err) reject(err) }) }).catch(err => { // console.log('e', err) reject(err) })
}).catch(function (error) {
return new Promise(async (resolve, reject) => {
const minABI = [{ constant: true, inputs: [], name: 'name', outputs: [{ name: '', type: 'bytes32' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'spender', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'approve', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [{ name: 'value', type: 'uint256' }], name: 'estimateFee', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'totalSupply', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'issuer', outputs: [{ name: '', type: 'address' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'from', type: 'address' }, { name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'transferFrom', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [], name: 'minFee', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'decimals', outputs: [{ name: '', type: 'uint8' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'value', type: 'uint256' }], name: 'setMinFee', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [{ name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'mint', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [{ name: 'value', type: 'uint256' }], name: 'burn', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [{ name: 'owner', type: 'address' }], name: 'balanceOf', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [], name: 'symbol', outputs: [{ name: '', type: 'bytes32' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: false, inputs: [{ name: 'account', type: 'address' }], name: 'addMinter', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [], name: 'renounceMinter', outputs: [], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: false, inputs: [{ name: 'to', type: 'address' }, { name: 'value', type: 'uint256' }], name: 'transfer', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'nonpayable', type: 'function' }, { constant: true, inputs: [{ name: 'account', type: 'address' }], name: 'isMinter', outputs: [{ name: '', type: 'bool' }], payable: false, stateMutability: 'view', type: 'function' }, { constant: true, inputs: [{ name: 'owner', type: 'address' }, { name: 'spender', type: 'address' }], name: 'allowance', outputs: [{ name: '', type: 'uint256' }], payable: false, stateMutability: 'view', type: 'function' }, { inputs: [], payable: false, stateMutability: 'nonpayable', type: 'constructor' }, { anonymous: false, inputs: [{ indexed: true, name: 'account', type: 'address' }], name: 'MinterAdded', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'account', type: 'address' }], name: 'MinterRemoved', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'from', type: 'address' }, { indexed: true, name: 'to', type: 'address' }, { indexed: false, name: 'value', type: 'uint256' }], name: 'Transfer', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'owner', type: 'address' }, { indexed: true, name: 'spender', type: 'address' }, { indexed: false, name: 'value', type: 'uint256' }], name: 'Approval', type: 'event' }, { anonymous: false, inputs: [{ indexed: true, name: 'from', type: 'address' }, { indexed: true, name: 'to', type: 'address' }, { indexed: true, name: 'issuer', type: 'address' }, { indexed: false, name: 'value', type: 'uint256' }], name: 'Fee', type: 'event' }]
const contract = new web3.eth.Contract(minABI, contractAddress)
contract.methods.name().call().then(name => {
contract.methods.symbol().call().then(symbol => {
contract.methods.balanceOf(address).call().then(balance => {
contract.methods.decimals().call().then(decimal => {
let nameFormat = web3.utils.toAscii(name).split('\u0000')[0]
let symbolFormat = web3.utils.toAscii(symbol).split('\u0000')[0]
resolve({ name: nameFormat ? nameFormat : symbolFormat, symbol: symbolFormat, balance: balance, decimal })
}).catch((e) => {
resolve({ name: '', symbol, balance: balance, decimal: 18 })
})
}).catch(err => {
// console.log('e', err)
reject(err)
})
}).catch(err => {
// console.log('e', err)
reject(err)
})
}).catch(err => {
// console.log('e', err)
reject(err)
})
})
})
}
This issue has been automatically marked as stale because it has not had recent activity. It will be closed in 7 days if no further activity occurs. Thank you for your contributions. If you believe this was a mistake, please comment.
This is still an issue
Expected behavior
Making a web3.js call to a contract that returns a struct of data like this:
Should return the values properly. If price is under 1 ETH in gwei, it works, but as soon as its over 1 ETH - it overflows.
Actual behavior
The call errors out with:
Steps to reproduce the behavior
Call a contract that returns a uint256 inside a struct that is over 10000000000000000 as the uint256
Environment
"web3": "^1.2.11"