I followed the conversation here to see if it would answer my question, but no it didn’t.
I understand that i have to use amount *= (amount ** tokenDecimal) before sending transactions with ERC20 transfer method, but when i do that i get an error.
I’m not sure what’s wrong because alot of articles have used this for examples.
Thanks for your help.
1 Like
Hi @sirphemmiey,
You can use a Big Number library.
The test below uses BN from @openzeppelin/test-helpers
SimpleToken.test.js
const { accounts, contract } = require('@openzeppelin/test-environment');
const {
BN, // Big Number support
constants, // Common constants, like the zero address and largest integers
expectEvent, // Assertions for emitted events
expectRevert, // Assertions for transactions that should fail
} = require('@openzeppelin/test-helpers');
const [ creator, other ] = accounts;
const { expect } = require('chai');
const SimpleToken = contract.fromArtifact('SimpleToken'); // Loads a compiled contract
describe('SimpleToken', function () {
it('transfer', async function () {
const token = await SimpleToken.new({ from: creator });
const amount = new BN("1000000000000000000000");
await token.transfer(other, amount, {from: creator});
expect(await token.balanceOf(other)).to.be.bignumber.equal(amount);
});
});
SimpleToken.sol
import "@openzeppelin/contracts/token/ERC20/ERC20.sol";
import "@openzeppelin/contracts/token/ERC20/ERC20Detailed.sol";
/**
* @title SimpleToken
* @dev Very simple ERC20 Token example, where all tokens are pre-assigned to the creator.
* Note they can later distribute these tokens as they wish using `transfer` and other
* `ERC20` functions.
*/
contract SimpleToken is Context, ERC20, ERC20Detailed {
/**
* @dev Constructor that gives _msgSender() all of existing tokens.
*/
constructor () public ERC20Detailed("SimpleToken", "SIM", 18) {
_mint(_msgSender(), 10000 * (10 ** uint256(decimals())));
}
}
Hi @abcoathup, thanks for your reply.
I have tried a number of different big number libraries, the problem still persist.
This is what i’m trying to do;
let amount = withdrawObj.amount;
const TokenDecimals = await this.getDecimal(symbol); // get the decimal of a token
amount *= (10 ** TokenDecimals);
Let's say the token decimal function returns 18 obviously, and i pass
2as the amount to transfer, it gives me
2000000000000000000` which appears too large for the ERC20 transfer function to process. I have tried the big number library, OZ test helper, bing interger, ethers, web3 etc all to no avail.
Thanks for your help once again.
1 Like
Hi @sirphemmiey,
We need to use the big number libraries multiply and power functions to do the calculation as the number is too big for JavaScript.
const tokenbits = (new BN(10)).pow(decimals);
const amount = (new BN(100)).mul(tokenbits);
See the following test for the SimpleToken contract above:
SimpleToken.test.js
const { accounts, contract } = require('@openzeppelin/test-environment');
const {
BN, // Big Number support
constants, // Common constants, like the zero address and largest integers
expectEvent, // Assertions for emitted events
expectRevert, // Assertions for transactions that should fail
} = require('@openzeppelin/test-helpers');
const [ creator, other ] = accounts;
const { expect } = require('chai');
const SimpleToken = contract.fromArtifact('SimpleToken'); // Loads a compiled contract
describe('SimpleToken', function () {
it('transfer', async function () {
const token = await SimpleToken.new({ from: creator });
const decimals = await token.decimals.call();
const tokenbits = (new BN(10)).pow(decimals);
const amount = (new BN(100)).mul(tokenbits);
console.log(`Amount: ${amount}`);
await token.transfer(other, amount, {from: creator});
expect(await token.balanceOf(other)).to.be.bignumber.equal(amount);
});
});
1 Like
Thanks for your reply.
It still displays the same error “(arg=”_value", coderType=“uint256”, value=10000000000000000)"
But when i changed the amount value after the bigNumber conversions to amount.toString()
, the transaction went successfully.
Could there be any issue with this way at the long run?
1 Like
Hi @sirphemmiey,
I assume it depends on the JavaScript library that you use to handle big numbers.
Just ensure that you have appropriate testing that you are transferring the required amount of tokens.
1 Like