I'm writing a simple exchange script. It contains my token with 18 decimal places and ether (which is very similar). Users can add buy / sell offerts and the script displays them.
I can send the addBuyOffert transaction there which has two arguments: tokensAmount and priceForOneUnit (one unit means equivalent for 1 ether). On the ending of the BUY function it multiplies tokens by price and removes sender's wei equivalent. When user cancels the offert, he gets wei back.
When I was testing the script on microvalues without any decimal places it was working great. For example I called buy offert with 10 tokens, 10 wei and it removed from my account 100 wei (10 tokens * 10 wei) and the offert was added without any problems. The problem appeared after adding decimals and working with greater numbers. The final price was for not 1 token but for 1000000000000000000. For example when I put 0.02 coin and 0.01 eth to add buy offert, it sends 20000000000000000, 10000000000000000 and tries to multiply it which fails with SafeMath. Also tried with div with 1 ether and it also didn't give me precise results.
Knowing this I changed my code a bit. This is what I did so far, but I keep in mind that this isn't the best solution, because the first "if" gives me wrong result - tried with 1.1, 1.1, expected 1.21, but got 1.1 of eth to remove.
uint eth = 1 ether;
if(tokensAmount > eth)
{
finalPrice = pBuyPrice.mul(tokensAmount.div(eth));
}
else if(tokensAmount < eth)
{
finalPrice = pBuyPrice.div(eth.div(tokensAmount));
}
else
{
finalPrice = pBuyPrice;
}
How can I make this calculation working properly?