ethers.utils.parseEther('0.0007000000000000001')
throws Error: underflow occurred (operation="division", fault="underflow", version=4.0.39)
How can I fix it?
That is arithmetic underflow though, you can鈥檛 have 0.1 wei. :)
I'm going to close this now, as this is expected behaviour, but please feel free to re-open or continue discussion here.
Thanks! :)
I think it's a rather common use case to convert a string value from an input html tag to a parsed big number, so it would be nice to have a regular expression as part of the constants object exported by ethers. Here's what I use in my app:
^[0-9]+.?[0-9]{0,18}$
Which matches:
But doesn't match:
It also doesn't match .4, which should be valid and doesn't match negative numbers like -1, which should sometimes be valid.
The regular expression that matches a fully qualified (but still flexible) number is a bit more complicated, but it may make sense to include.
In v5, it would be more useful to probably use something like:
function valid(value) {
try {
ethers.FixedNumber.fromString(value, "fixed128x18");
return true;
} catch (e) { }
return false;
}
as this allows checking for total bit width as well. Other common things may be "ufixed128x18" for positive-only, or for satoshis, "ufixed128x8" could be used. In general, this function would be called text.oninput and used to update any "submit" button, or highlight the invalid field.
For the simpleminded folk amongst us.
The issue is that ether (and most ERC20 tokens) only support 18 decimals.
So what I use is a simple function to round the string down before I pass it to ethers.utils.parseEther
function roundCryptoValueString(str, decimalPlaces=18){
const arr = str.split(".");
const fraction = arr[1] .substr(0, decimalPlaces);
return arr[0] + "." + fraction;
}
For what it's worth, I ended up building my own solution for this problem.
It's a tiny npm package called evm-fp, which works like this;
import { BigNumber } from "@ethersproject/bignumber";
import fp from "evm-fp";
const foo: BigNumber = fp("3.1415");
const bar: BigNumber = fp("115792089237316195423570985008687907853269984665640564039457.584007913129639935");
const baz: BigNumber = fp("100e6", 6);
Most helpful comment
It also doesn't match
.4, which should be valid and doesn't match negative numbers like-1, which should sometimes be valid.The regular expression that matches a fully qualified (but still flexible) number is a bit more complicated, but it may make sense to include.
In v5, it would be more useful to probably use something like:
as this allows checking for total bit width as well. Other common things may be "ufixed128x18" for positive-only, or for satoshis, "ufixed128x8" could be used. In general, this function would be called
text.oninputand used to update any "submit" button, or highlight the invalid field.