[Ethereum] Random BigNumber in ethers.js

bignumberethers.jsrandom

I'm looking to generate a random ethers.js BigNumber in a certain range. While this question has answers about random number generation, the answers as of this writing (April 2021) only cover BigInt, BN.js, and web3.js, and in addition, does not discuss ranges.

My primary use for this is generating random token amounts during tests. Tokens traditionally have a large amount of decimal places, making Big Number libraries necessary.

I've tried adopting the answers there, but cannot get them to work ethers, even before addressing the issue of creating a min/max range. For example, I tried:

const randBytes = randomBytes(16); // from the node.js crypto library
const amount = BigNumber.from(`0x${randBytes.toString()}`);

or in place of the second line:

const amount = BigNumber.from(`0x${new BN(randBytesMint.toString('hex'), 16)}`);

which give me:

Error: invalid BigNumber value (argument="value", value=undefined, code=INVALID_ARGUMENT, version=bignumber/5.0.13)```

Since in my personal case I do not need security guarantees, I'm also open to a solution using Math.random() and then scaling up using ethers.utils.parseUnits(), though secure random number answers are certainly appreciated too.

Best Answer

To generate a number in the entire uint256 range

ethers.BigNumber.from(ethers.utils.randomBytes(32))

You can add function wrappers around that if you need it in a certain range such as

function randomBN(max) {
  return ethers.BigNumber.from(ethers.utils.randomBytes(32)).mod(max);
}